<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><div id="myscoll"></div><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>TS基础 | 晚夜微雨问海棠のBlog</title><meta name="keywords" content="ts"><meta name="author" content="晚夜微雨问海棠"><meta name="copyright" content="晚夜微雨问海棠"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="这是小生对 TypeScript 的一些拙见,有不对之处还望评论区留言,以便及时更正  TypeScript 介绍 （1） TypeScript 是由微软开发的一款开源的编程语言。 （2）TypeScript 是 Javascript 的超集，遵循最新的 ES6、Es5 规范。TypeScript 扩展了 JavaScript 的语法。 （3）TypeScript 更像后端 java、C#这样的面">
<meta property="og:type" content="article">
<meta property="og:title" content="TS基础">
<meta property="og:url" content="http://example.com/posts/d044eab7.html">
<meta property="og:site_name" content="晚夜微雨问海棠のBlog">
<meta property="og:description" content="这是小生对 TypeScript 的一些拙见,有不对之处还望评论区留言,以便及时更正  TypeScript 介绍 （1） TypeScript 是由微软开发的一款开源的编程语言。 （2）TypeScript 是 Javascript 的超集，遵循最新的 ES6、Es5 规范。TypeScript 扩展了 JavaScript 的语法。 （3）TypeScript 更像后端 java、C#这样的面">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fwww.linuxeden.com%2Fwp-content%2Fuploads%2F2018%2F07%2F4d61b0d3264e651fde2e5a07d856381323d.jpg&refer=http%3A%2F%2Fwww.linuxeden.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664441895&t=eeff26717d91ad1e5d6930cd5f9867b7">
<meta property="article:published_time" content="2022-11-12T03:28:51.689Z">
<meta property="article:modified_time" content="2022-09-09T05:52:11.181Z">
<meta property="article:author" content="晚夜微雨问海棠">
<meta property="article:tag" content="TypeScript">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fwww.linuxeden.com%2Fwp-content%2Fuploads%2F2018%2F07%2F4d61b0d3264e651fde2e5a07d856381323d.jpg&refer=http%3A%2F%2Fwww.linuxeden.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664441895&t=eeff26717d91ad1e5d6930cd5f9867b7"><link rel="shortcut icon" href="/img/favicon.png"><link rel="canonical" href="http://example.com/posts/d044eab7"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//fonts.googleapis.com" crossorigin=""/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="manifest" href="/manifest.json"/><meta name="msapplication-TileColor" content="#49b1f5"/><link rel="apple-touch-icon" sizes="180x180" href="/img/siteicon/128.png"/><link rel="icon" type="image/png" sizes="32x32" href="/img/siteicon/32.png"/><link rel="icon" type="image/png" sizes="16x16" href="/img/siteicon/16.png"/><link rel="mask-icon" href="/img/siteicon/128.png" color="#5bbad5"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Titillium+Web&amp;display=swap" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: {"path":"/search.xml","preload":false,"languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: {"defaultEncoding":2,"translateDelay":0,"msgToTraditionalChinese":"繁","msgToSimplifiedChinese":"简"},
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":150},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: true,
    post: true
  },
  runtime: '天',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: {"limitCount":650,"languages":{"author":"作者: 晚夜微雨问海棠","link":"链接: ","source":"来源: 晚夜微雨问海棠のBlog","info":"著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"}},
  lightbox: 'fancybox',
  Snackbar: {"chs_to_cht":"你已切换为繁体","cht_to_chs":"你已切换为简体","day_to_night":"你已切换为深色模式","night_to_day":"你已切换为浅色模式","bgLight":"#49b1f5","bgDark":"#1f1f1f","position":"top-right"},
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: true,
  isAnchor: true
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'TS基础',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2022-09-09 13:52:11'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><link rel="stylesheet" href="/css/custom.css" media="defer" onload="this.media='all'"> <link rel="stylesheet" href="/swiper/swiper.min.css"> <link rel="stylesheet" href="/swiper/swiperstyle.css"> <link rel="stylesheet" href="/css/rightMenu.css"> <link rel="stylesheet" href="/css/constrain.css"><!-- hexo injector head_end start --><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper/swiper-bundle.min.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Zfour/Butterfly-card-history/baiduhistory/css/main.css"><link rel="stylesheet" href="https://npm.elemecdn.com/hexo-butterfly-categories-card@1.0.0/lib/categorybar.css"><link rel="stylesheet" href="https://cdn.cbd.int/hexo-butterfly-clock-anzhiyu/lib/clock.min.css" /><link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Zfour/Butterfly-double-row-display@1.00/cardlistpost.min.css"/>
<style>#recent-posts > .recent-post-item >.recent-post-info > .article-meta-wrap > .tags:before {content:"\A";
  white-space: pre;}#recent-posts > .recent-post-item >.recent-post-info > .article-meta-wrap > .tags > .article-meta__separator{display:none}</style>
<link rel="stylesheet" href="https://cdn.cbd.int/anzhiyu-blog@2.0.3/css/runtime/runtime.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.cbd.int/hexo-butterfly-swiper-anzhiyu@1.0.4/lib/swiper.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.cbd.int/hexo-butterfly-swiper-anzhiyu@1.0.4/lib/swiperstyle.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.cbd.int/hexo-butterfly-wowjs/lib/animate.min.css" media="print" onload="this.media='screen'"><link rel="stylesheet" href="https://cdn.cbd.int/hexo-butterfly-tag-plugins-plus@latest/lib/assets/font-awesome-animation.min.css" media="defer" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.cbd.int/hexo-butterfly-tag-plugins-plus@latest/lib/tag_plugins.css" media="defer" onload="this.media='all'"><script src="https://cdn.cbd.int/hexo-butterfly-tag-plugins-plus@latest/lib/assets/carousel-touch.js"></script><!-- hexo injector head_end end --><meta name="generator" content="Hexo 6.2.0"><link rel="alternate" href="/atom.xml" title="晚夜微雨问海棠のBlog" type="application/atom+xml">
</head><body><div id="loading-box"><div class="loading-left-bg"></div><div class="loading-right-bg"></div><div class="spinner-box"><div class="configure-border-1"><div class="configure-core"></div></div><div class="configure-border-2"><div class="configure-core"></div></div><div class="loading-word">加载中...</div></div></div><div id="web_bg"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src= "" data-lazy-src="https://img2.woyaogexing.com/2022/06/28/de1ce3dc65468fd4!400x400.jpg" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">97</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">31</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">17</div></a></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/bangumis/index.html"><i class="fa-fw fas fa-home"></i><span> 追番</span></a></div><div class="menus_item"><a class="site-page" href="/comments/"><i class="fa-fw fas fa-envelope"></i><span> 留言板</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 归档</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> 生活馆</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" target="_blank" rel="noopener" href="http://81.69.189.243:8082/"><i class="fa-fw fas fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/movies/"><i class="fa-fw fas fa-video"></i><span> 电影</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友情链接</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fwww.linuxeden.com%2Fwp-content%2Fuploads%2F2018%2F07%2F4d61b0d3264e651fde2e5a07d856381323d.jpg&amp;refer=http%3A%2F%2Fwww.linuxeden.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1664441895&amp;t=eeff26717d91ad1e5d6930cd5f9867b7')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/">晚夜微雨问海棠のBlog</a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/bangumis/index.html"><i class="fa-fw fas fa-home"></i><span> 追番</span></a></div><div class="menus_item"><a class="site-page" href="/comments/"><i class="fa-fw fas fa-envelope"></i><span> 留言板</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 归档</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> 生活馆</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" target="_blank" rel="noopener" href="http://81.69.189.243:8082/"><i class="fa-fw fas fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/movies/"><i class="fa-fw fas fa-video"></i><span> 电影</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友情链接</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">TS基础</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2022-11-12T03:28:51.689Z" title="发表于 2022-11-12 11:28:51">2022-11-12</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2022-09-09T05:52:11.181Z" title="更新于 2022-09-09 13:52:11">2022-09-09</time></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">8.7k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>30分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="TS基础"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><div class="tip warning"><p>这是小生对 TypeScript 的一些拙见,有不对之处还望评论区留言,以便及时更正</p>
</div>
<h1 id="TypeScript-介绍"><a href="#TypeScript-介绍" class="headerlink" title="TypeScript 介绍"></a>TypeScript 介绍</h1><blockquote>
<p>（1） TypeScript 是由微软开发的一款开源的编程语言。</p>
<p>（2）TypeScript 是 Javascript 的超集，遵循最新的 ES6、Es5 规范。TypeScript 扩展了 JavaScript</p>
<p>的语法。</p>
<p>（3）TypeScript 更像后端 java、C#这样的面向对象语言，可以让 js 开发大型企业项目。</p>
<p>（4）最新的 Vue 、React 也可以集成 TypeScript</p>
<p>（5）Nodejs 框架 Nestjs、midway 中用的就是 TypeScript 语法。</p>
<p>（6）TypeScript 是微软的，TS直接用微软自己的 C#语法、C#直接用的Java 的语法</p>
<p>（7）JS 有的 TS 都有，JS 没有的 TS 也有</p>
<p>（8）TypeScript 可理解成：Type + JavaScript，也就是在 JS基础上，为 JS 添加了 <code>类型支持</code></p>
<p>（9）TS 无法直接运行，需要转换为 JS 才能运行</p>
<p>（10）JS为弱类型语言，就是因为JS类型的不确定性，有了TS类规范类型，如虎添翼</p>
<p>（11）TS属于静态类型的编程语言，JS属于动态类型编程语言，静态类型：编译期做类型检查、动态类型：执行器做类型检查、而代码是先编译后执行</p>
<p>（12）TS<code>类型推断</code>机制，<code>不需要</code>在代码中的<code>每个地方都显示的标注</code></p>
</blockquote>
<h2 id="Typescript-安装-编译"><a href="#Typescript-安装-编译" class="headerlink" title="Typescript 安装 编译"></a>Typescript 安装 编译</h2><ol>
<li><p>在使用 npm 命令之前电脑必须得安装 nodejs</p>
</li>
<li><p>安装：</p>
<blockquote>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install -g typescript</span><br></pre></td></tr></table></figure>
</blockquote>
</li>
<li><p>查看版本：</p>
<blockquote>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tsc -v</span><br></pre></td></tr></table></figure>
<p>官方提供了 <code>tsc</code> 命令。实现 TS - JS 的转换</p>
</blockquote>
</li>
<li><p>运行：</p>
<blockquote>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tsc helloworld.ts</span><br></pre></td></tr></table></figure>
</blockquote>
</li>
<li><p>编译并运行 TS 代码，步骤</p>
<ol>
<li>创建 .ts 文件（注意：TS 文件 后缀名为 .ts）</li>
<li>将 TS 编译为 JS：在终端中输入命令，tsc TS文件名（此时同级目录中会出现同名的 JS 文件）</li>
<li>执行 JS 代码：在终端中输入命令，node JS 文件名 即可运行</li>
</ol>
</li>
<li><p>简化运行 TS 步骤</p>
<ol>
<li><p>使用 <code>ts-node</code> 包，直接在 Node.js 中运行 TS 代码</p>
</li>
<li><p>安装方式：</p>
<ol>
<li>```bash<br>npm i -g ts-node<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">      2. ts-node 包提供了 ts-node 命令</span><br><span class="line"></span><br><span class="line">   3. 使用方式：ts-node TS文件</span><br><span class="line"></span><br><span class="line">## Typescript 开发工具 Vscode 自动编译 .ts 文件</span><br><span class="line"></span><br><span class="line">1. 创建 tsconfig.json 文件 tsc --init 生成配置文件</span><br><span class="line"></span><br><span class="line">2. ![](img/Typescript%20%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7%20Vscode%20%E8%87%AA%E5%8A%A8%E7%BC%96%E8%AF%91.ts%20%E6%96%87%E4%BB%B6.png)</span><br><span class="line"></span><br><span class="line">3. outDir：表示再创建一个 js 文件夹，编译好的 js 文件放在 js 文件夹下</span><br><span class="line"></span><br><span class="line">   &gt; （1）最新版本 vscode 点击:</span><br><span class="line">   &gt;</span><br><span class="line">   &gt; （2） 终端-&gt;  运行任务 -&gt;  typescript  -&gt;  tsc:监视 -&gt; tsconfig.json</span><br><span class="line">   &gt;</span><br><span class="line">   &gt; （3）然后就 可以自动生成代码了</span><br><span class="line">   &gt;</span><br><span class="line">   &gt; （4）注意：重复、或 冲突、导致的监视失败</span><br><span class="line"></span><br><span class="line"># 类型注解</span><br><span class="line"></span><br><span class="line">1. TypeScript 中为了使编写的代码更规范，更有利于维护，增加了类型校验，</span><br><span class="line"></span><br><span class="line">2. 在 TypeScript 中主要给我们了10种类型</span><br><span class="line"></span><br><span class="line">   &gt; （1）布尔类型（boolean）</span><br><span class="line">   &gt;</span><br><span class="line">   &gt; （2）数字类型（number）</span><br><span class="line">   &gt;</span><br><span class="line">   &gt; （3）字符串类型（string）</span><br><span class="line">   &gt;</span><br><span class="line">   &gt; （4）数组类型 （array）</span><br><span class="line">   &gt;</span><br><span class="line">   &gt; （5）元组类型（tuple）</span><br><span class="line">   &gt;</span><br><span class="line">   &gt; （6） 枚举类型（enum）</span><br><span class="line">   &gt;</span><br><span class="line">   &gt; （7）任意类型（any）</span><br><span class="line">   &gt;</span><br><span class="line">   &gt; （8）null 和 undefined</span><br><span class="line">   &gt;</span><br><span class="line">   &gt; （9）void 类型</span><br><span class="line">   &gt;</span><br><span class="line">   &gt; （10）never 类型</span><br><span class="line"></span><br><span class="line">3. 说明：</span><br><span class="line"></span><br><span class="line">   &gt; ```ts</span><br><span class="line">   &gt; let age:number - 18</span><br></pre></td></tr></table></figure>
&gt;<blockquote>
<p>说明：代码中的：number 就是类型注解</p>
<p>作用：为变量<code>添加类型约束</code></p>
<p>解释：约定了什么类型，就只能给变量赋什么类型的值，否则报错</p>
</blockquote>
</li>
</ol>
</li>
</ol>
</li>
<li><p>常用类型分类：JS已有类型，TS新增类型</p>
<ol>
<li>JS已有类型<ol>
<li>原始类型：number、string、boolean、null、undefined、Symbol</li>
<li>对象类型：Object（包括、数组、对象、函数等对象）</li>
</ol>
</li>
<li>TS新增的类型<ol>
<li>联合类型 |（竖线） 、自定义类型（类型别名）、接口、元组、字面量类型、枚举、void、any等</li>
</ol>
</li>
</ol>
</li>
</ol>
<h2 id="布尔类型（boolean）"><a href="#布尔类型（boolean）" class="headerlink" title="布尔类型（boolean）"></a>布尔类型（boolean）</h2><ol>
<li>布尔类型（boolean） true 或 false</li>
</ol>
<blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 声明</span></span><br><span class="line"><span class="keyword">var</span> <span class="attr">flag</span>: boolean = <span class="literal">true</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="数字类型-（number）"><a href="#数字类型-（number）" class="headerlink" title="数字类型 （number）"></a>数字类型 （number）</h2><ol>
<li>可用于浮点型，ts中没有区分整形和浮点型</li>
</ol>
<blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> <span class="attr">a</span>: number = <span class="number">123</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a)</span><br><span class="line"></span><br><span class="line">a = <span class="number">12.3</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a)</span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="字符串类型（string）"><a href="#字符串类型（string）" class="headerlink" title="字符串类型（string）"></a>字符串类型（string）</h2><ol>
<li>只能接收字符串类型</li>
</ol>
<blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> <span class="attr">str</span>: string = <span class="string">&#x27;this is ts&#x27;</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="数组类型-（array）"><a href="#数组类型-（array）" class="headerlink" title="数组类型 （array）"></a>数组类型 （array）</h2><ol>
<li>数组类型 （array）ts中的数组有三种</li>
</ol>
<h3 id="第一种方式：只能写对应的类型的值"><a href="#第一种方式：只能写对应的类型的值" class="headerlink" title="第一种方式：只能写对应的类型的值"></a>第一种方式：只能写对应的类型的值</h3><blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="attr">arr</span>: number[] = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arr)</span><br><span class="line"><span class="keyword">const</span> <span class="attr">arr1</span>: string[] = [<span class="string">&#x27;1&#x27;</span>, <span class="string">&#x27;2&#x27;</span>, <span class="string">&#x27;3&#x27;</span>, <span class="string">&#x27;4&#x27;</span>, <span class="string">&#x27;5&#x27;</span>]</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arr1)</span><br></pre></td></tr></table></figure>
</blockquote>
<h3 id="第二种方式：泛型-同样只能写对应类型的值"><a href="#第二种方式：泛型-同样只能写对应类型的值" class="headerlink" title="第二种方式：泛型,同样只能写对应类型的值"></a>第二种方式：泛型,同样只能写对应类型的值</h3><blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="attr">arr2</span>: <span class="title class_">Array</span>&lt;number&gt; = [<span class="number">11</span>, <span class="number">22</span>, <span class="number">33</span>, <span class="number">44</span>]</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arr2)</span><br><span class="line"><span class="keyword">const</span> <span class="attr">arr3</span>: <span class="title class_">Array</span>&lt;string&gt; = [<span class="string">&#x27;11&#x27;</span>, <span class="string">&#x27;22&#x27;</span>, <span class="string">&#x27;33&#x27;</span>, <span class="string">&#x27;44&#x27;</span>]</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arr3)</span><br></pre></td></tr></table></figure>
</blockquote>
<h3 id="第三种方式：使用-any-类型，可写任意类型的值"><a href="#第三种方式：使用-any-类型，可写任意类型的值" class="headerlink" title="第三种方式：使用 any 类型，可写任意类型的值"></a>第三种方式：使用 any 类型，可写任意类型的值</h3><blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> <span class="attr">arr4</span>: any[] = [<span class="string">&#x27;1213&#x27;</span>, <span class="number">21</span>, <span class="number">3</span>, <span class="literal">true</span>]</span><br><span class="line"><span class="keyword">let</span> <span class="attr">arr</span>: (number | string)[] = [<span class="string">&#x27;1&#x27;</span>, <span class="number">1</span>]</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arr4)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arr)</span><br></pre></td></tr></table></figure>
<p>注意：|  在TS中叫做<code>联合类型</code></p>
</blockquote>
<h2 id="元组类型（tuple）"><a href="#元组类型（tuple）" class="headerlink" title="元组类型（tuple）"></a>元组类型（tuple）</h2><ol>
<li><p>元组类型（tuple）属于数组的一种,可以指定数组中额类型</p>
<blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="attr">tup</span>: [string, number, boolean] = [<span class="string">&#x27;ts&#x27;</span>, <span class="number">3</span>, <span class="literal">true</span>]</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(tup)</span><br></pre></td></tr></table></figure>
</blockquote>
</li>
<li><p>例如：</p>
<ol>
<li>在地图中，使用经纬度来标记坐标，可以使用数组来记录，那该数组中只有两个元素，且都为number类型，使用number[ ] 就会有缺点</li>
<li>number[ ]  不严谨，因为该类型的数组中可以出现任意多个数字，这时就需要用到<code>元组（Tuple）</code>了</li>
</ol>
</li>
<li><p>元古类型是另一种类型的数组。他<code>确切的知道包含多少个元素，以及特定索引对应的类型</code></p>
<ol>
<li>```js<br>let position:[number,number] = [14.12,15.45]<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">4. 解释：</span><br><span class="line"></span><br><span class="line">   1. 元组类型可以确切的标记出有多少个元素，以及每个元素的类型</span><br><span class="line">   2. 该实例中，元素有两个，每个元素都是`number`</span><br><span class="line"></span><br><span class="line">5.</span><br><span class="line"></span><br><span class="line">## 枚举类型（enum）</span><br><span class="line"></span><br><span class="line">1. 枚举类型（enum）主要用来定义标识符</span><br><span class="line">2. 枚举：定义一组命名常量，它描述一个值，该值可以是这些命名常量中的一个</span><br><span class="line">3. 解析：</span><br><span class="line">   1. 使用 `enum` 关键字定义枚举</span><br><span class="line">   2. 约定枚举名词，枚举中的值以大写字母开头</span><br><span class="line">   3. 枚举中的多个值之间通过，（逗号）来隔开</span><br><span class="line">   4. 定义好枚举后，直接使用枚举名称作为类型注解</span><br><span class="line">4. 注意：继承枚举后，值应该是枚举成员中的任意一个</span><br><span class="line">5. 类似于JS对象，直接通过`点（.）语法`访问枚举的成员</span><br><span class="line">6. 数字枚举：</span><br><span class="line">   1. 枚举中成员是有值的，默认为：从0开始自增的数值</span><br><span class="line">   2. 我们吧枚举成员的值为数字的枚举，称为：`数字枚举`</span><br><span class="line">   3. 当然也可给枚举中的成员赋初始值</span><br><span class="line">7. 字符串枚举：</span><br><span class="line">   1. 枚举成员的值是字符串</span><br><span class="line">   2. 字符串没有自增长行为，因此，字符串枚举的每个成员必须有初始值</span><br><span class="line">8. 枚举不仅用作类型，还提供值，枚举成员都是有值的</span><br><span class="line">9. 也就是说，其他类型在编译为JS代码时自动移除，但是，枚举类型会被编译为JS代码</span><br><span class="line">10. 一般情况下，推荐使用 字面量类型+联合类型组合方式，因为相比枚举，这种方式更直观、简介、高效</span><br><span class="line"></span><br><span class="line">&gt; ```js</span><br><span class="line">&gt; enum flag1 &#123;</span><br><span class="line">&gt; success = 1,</span><br><span class="line">&gt; error = 2,</span><br><span class="line">&gt; &#125;</span><br><span class="line">&gt; var f: flag1 = flag1.error</span><br><span class="line">&gt; console.log(f) // f = 2</span><br><span class="line">&gt; console.log(flag1.error) // f = 2</span><br></pre></td></tr></table></figure>
</li>
</ol>
</li>
</ol>
<h2 id="任意类型（any）"><a href="#任意类型（any）" class="headerlink" title="任意类型（any）"></a>任意类型（any）</h2><ol>
<li>任意类型的用处:</li>
<li>比如获取一个元素对象，在ts中,用其他类型接收会报错，必须使用任意类型接收</li>
<li>原则不推荐使用 any类型，这回让 TypeScript 变为 ‘AnyScript’（失去 TS 类型保护优势）</li>
<li>因为当值为 any 时，可以进行任意的操作，不会有代码提示，即便存在错误</li>
<li>可以临时使用 any类型、</li>
<li>隐式any类型的情况，<ol>
<li>声明变量不提供类型也不提供默认值</li>
<li>函数参数不加类型</li>
<li>注意：因为不推荐 any，所以这两种情况，都应该提供类型</li>
</ol>
</li>
</ol>
<blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> <span class="attr">num</span>: any = <span class="number">123</span></span><br><span class="line">num = <span class="literal">true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(num)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 任意类型的用处</span></span><br><span class="line"><span class="comment">// 比如获取一个元素对象，在ts中,用其他类型接收会报错，必须使用任意类型接收</span></span><br><span class="line"><span class="keyword">var</span> box = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;#box&#x27;</span>)</span><br><span class="line">box.<span class="property">style</span>.<span class="property">color</span> = <span class="string">&#x27;red&#x27;</span> <span class="comment">// 错误写法</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> <span class="attr">box</span>: any = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;#box&#x27;</span>)</span><br><span class="line">box.<span class="property">style</span>.<span class="property">color</span> = <span class="string">&#x27;red&#x27;</span> <span class="comment">// 此时是正确的</span></span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="null-和-undefined"><a href="#null-和-undefined" class="headerlink" title="null 和 undefined"></a>null 和 undefined</h2><ol>
<li>null 和 undefined ，是其他（never类型）数据类型的子类型</li>
<li>用法：</li>
<li>一个元素可能是 number 类型，可能是 null，可能是 undefined 类型</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"> <span class="keyword">var</span> <span class="attr">num11</span>: number</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(num11) <span class="comment">// 输出 undefined,报错</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> <span class="attr">num11</span>: <span class="literal">undefined</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(num11) <span class="comment">// 输出 undefined, 正确</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 定义 赋值，不会报错</span></span><br><span class="line"><span class="keyword">var</span> <span class="attr">numer</span>: number | <span class="literal">undefined</span></span><br><span class="line">numer = <span class="number">123</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(numer) <span class="comment">// 正确</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 定义未赋值，也不会报错</span></span><br><span class="line"><span class="keyword">var</span> <span class="attr">abc</span>: number | <span class="literal">undefined</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(abc) <span class="comment">// 正确</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 用法：一个元素可能是 number 类型，可能是 null，可能是 undefined 类型</span></span><br><span class="line"><span class="keyword">var</span> <span class="attr">n</span>: number | <span class="literal">null</span> | <span class="literal">undefined</span></span><br><span class="line">n = <span class="number">123</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(n)</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h2 id="void类型"><a href="#void类型" class="headerlink" title="void类型"></a>void类型</h2><ol>
<li>void类型：TypeScript 中的 void 表示没有任何类型，一般用于定义方法的时候没有返回值</li>
</ol>
<blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// ES5 语法</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">run</span>(<span class="params"></span>) &#123;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(run)</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">run</span>()</span><br><span class="line"><span class="comment">// ts 语法,用于没有返回值的时候</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">runing</span>(<span class="params"></span>): <span class="keyword">void</span> &#123;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(run)</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">runing</span>()</span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="never类型"><a href="#never类型" class="headerlink" title="never类型"></a>never类型</h2><ol>
<li>never类型：是其他类型，代表从不会出现的值</li>
<li>（包括 null 和 undefined）的子类型，代表从不会出现的值，</li>
<li>这意味着声明 never 的变量只能被 never 类型所赋值</li>
</ol>
<blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> <span class="attr">aer</span>: <span class="literal">undefined</span></span><br><span class="line">aer = <span class="literal">undefined</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> <span class="attr">ber</span>: <span class="literal">null</span></span><br><span class="line">ber = <span class="literal">null</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> <span class="attr">wrq</span>: never</span><br><span class="line">wrq = <span class="number">123</span> <span class="comment">// 错误写法</span></span><br><span class="line"></span><br><span class="line">wrq = (<span class="function">() =&gt;</span> &#123;</span><br><span class="line"><span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">Error</span>(<span class="string">&#x27;错误&#x27;</span>)</span><br><span class="line">&#125;)()</span><br><span class="line"></span><br><span class="line">wrq = (():<span class="function"><span class="params">number</span> =&gt;</span> &#123;</span><br><span class="line"><span class="keyword">return</span> <span class="number">123</span></span><br><span class="line">&#125;)()</span><br></pre></td></tr></table></figure>
</blockquote>
<h2 id="函数类型"><a href="#函数类型" class="headerlink" title="函数类型"></a>函数类型</h2><ol>
<li><p>函数的类型：实际上就是函数<code>参数</code>和<code>返回值</code>的类型</p>
</li>
<li><p>为函数指定类型的两种方式：</p>
<ol>
<li>单独指定参数，返回值的类型，</li>
<li>同时指定参数，返回值的类型</li>
</ol>
</li>
<li><p>单独指定参数</p>
<ol>
<li><p>```js<br>function add(num1:number,num2:number):number{</p>
<pre><code>return num1+num2
</code></pre><p>}<br>const add =(num1:number,num2:number):number=&gt;{</p>
<pre><code>return num1+num2
</code></pre><p>}</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">4. 同时指定参数，返回值的类型</span><br><span class="line"></span><br><span class="line">   1. ```js</span><br><span class="line">      const add:(num1:number,num2:number)=&gt;number=(num1,num2)&#123;</span><br><span class="line">          return num1 + num2</span><br><span class="line">      &#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>解析：当函数做为表达式时，可以通过<code>类似箭头函数形式的语法</code>来为函数添加类型</p>
</li>
<li><p>注意：这种形式只适用函数表达式</p>
</li>
</ol>
</li>
</ol>
<h2 id="对象类型"><a href="#对象类型" class="headerlink" title="对象类型"></a>对象类型</h2><ol>
<li><p>JS中的对象是有属性和方法构成的，而TS中对象类型就是在描述对象的结构</p>
</li>
<li><p>```js<br>let person:{name:string; age:number; sayHi():void}={</p>
<pre><code>name:&#39;jack&#39;,
age:19,
sayHi()&#123;&#125;
</code></pre><p>}</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">3. 解析：</span><br><span class="line"></span><br><span class="line">   1. 直接用 &#123;&#125; 来描述对象结构，属性采用`属性名：类型`的形式；方法采用发`方法名()：返回值类型`的形式</span><br><span class="line">   2. 如果方法有参数，就在方法名后面的小括号指定参数类型，（比如：greet(name:string)：void）</span><br><span class="line">   3. 在一行代码中指定对象的多个属性类型时，使用；（分号）来分隔</span><br><span class="line">   4. 如果一行代码只指定一个属性类型，（通过换行来分隔多个属性类型），可以去掉；（分号）</span><br><span class="line">   5. 方法的类型也可以使用箭头函数形式（比如：sayHi() =&gt; void）</span><br><span class="line"></span><br><span class="line">### 对象的可选属性</span><br><span class="line"></span><br><span class="line">1. 对象的属性和方法也是可选的，此时就需要用到可选属性了</span><br><span class="line"></span><br><span class="line">2. 比如：我们在使用 axios(&#123;…&#125;)时，如果发送了 Get 请求，method 属性就可以省略</span><br><span class="line"></span><br><span class="line">3. ```js</span><br><span class="line">   // 对象的可选属性</span><br><span class="line">   function myAxios(config: &#123; url: string; method?: string &#125;) &#123;&#125;</span><br><span class="line">   myAxios(&#123;</span><br><span class="line">     url: &#x27;&#x27;,</span><br><span class="line">   &#125;)</span><br></pre></td></tr></table></figure>
</li>
<li><p><code>可选属性</code>的语法与函数可选参数的语法一致，都使用了 ？（问号）来表示</p>
</li>
</ol>
<p>5.</p>
<h2 id="类型别名"><a href="#类型别名" class="headerlink" title="类型别名"></a>类型别名</h2><ol>
<li><p><code>类型别名</code>（自定义类型）：为任意类型起别名</p>
</li>
<li><p>关键字：type</p>
</li>
<li><p>使用场景：当同一类型（复杂）被多次使用时，可以通过类型别名，简化该类型的使用</p>
</li>
<li><p>解释：</p>
<ol>
<li>使用 type 关键字来创建类型别名</li>
<li>类型别名（比如，此处的 CustomArray），可以是任意合法的变量名称</li>
<li>创建类型别名后，直接<code>使用该类型别名作为变量的类型注解</code>即可</li>
</ol>
</li>
<li><p>```js<br>type CustomArray = (number | string )[]<br>let arr1:CustomArray = [1,’a’,3,’b’]<br>let arr2:CustomArray = [‘x’,’y’,6,7]</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 类型推论</span><br><span class="line"></span><br><span class="line">1. 在 TS 中，某些没有明确指出类型的地方，TS 的类型推论机制会帮助提供类型</span><br><span class="line"></span><br><span class="line">2. 换句话说：由于类型推论的存在，这些地方，类型注解可以`省略`不写</span><br><span class="line"></span><br><span class="line">3. ```js</span><br><span class="line">   let age = 18 // 鼠标移除变量名称，age</span><br><span class="line">   let age1:number // Ts自动推断出变量 age，为 number 类型</span><br><span class="line">   function add (num1:number,num2:number):number // 都是number 类型，TS 可直接推论出，返回结果是 number类型</span><br></pre></td></tr></table></figure>
</li>
<li><p>注意：这两种情况下，类型注解可以省略不写</p>
</li>
<li><p>推荐：<code>能省略类型注解的地方就省略</code>（偷懒，充分利用TS类型推论能力，提升开发效率）</p>
</li>
<li><p>技巧：如果不知道类型，可以通过鼠标放在变量名称上，利用 VSCode 的提示来查看类型</p>
</li>
</ol>
<h2 id="类型断言"><a href="#类型断言" class="headerlink" title="类型断言"></a>类型断言</h2><ol>
<li><p>有时候你会比 TS 更加明确一个值的类型，此时，可以使用<code>类型断言来指定更具体</code>的类型</p>
</li>
<li><p>比如：</p>
<ol>
<li>```html<br><a target="_blank" rel="noopener" href='http://www.baidu.cn'>百度</a><br>const alink = document.getElementById(‘link’)<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">3. 注意：</span><br><span class="line"></span><br><span class="line">   1. getElementById 方法返回值的类型是 HTMLElement，</span><br><span class="line">   2. 该类型只包括所有标签公共的属性和方法，`不包含 a标签特有的 href 属性`</span><br><span class="line"></span><br><span class="line">4. 因此，这个类型太宽泛（不具体），无法操作 href 等 a 标签特有的属性或方式</span><br><span class="line"></span><br><span class="line">5. 解决方式：这种情况下就需要使用`类型断言，指定更加具体的类型`</span><br><span class="line"></span><br><span class="line">6. 使用方式：关键字：` as 或者 &lt;&gt; 语法`</span><br><span class="line"></span><br><span class="line">   1. ```js</span><br><span class="line">      const aLink = document.getElementById(&#x27;link&#x27;) as HTMLAnchorElement</span><br></pre></td></tr></table></figure>
</li>
</ol>
</li>
<li><p>解释：</p>
<ol>
<li>使用 as 关键字实现了类型断言</li>
<li>关键字 as 后面的类型是一个更加具体的类型（HTMLAnchorElement 是 HTMLElement 的子类型）</li>
<li>通过类型断言，aLink 的类型变的更加具体，这样就可以访问到 a 标签特有的属性或方式了</li>
</ol>
</li>
<li><p>另一种语法：使用 <code>&lt;&gt;</code> 语法，这种语法不常用，知道即可</p>
<ol>
<li><p>```js<br>const aLink = <HTMLAnchorElement> document.getElementById(‘#link’)</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">9. 技巧：在浏览器控制台，通过 console.dir（）打印 DOM元素，在属性列表的最后面，即可看到该元素的类型</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## 字面量类型</span><br><span class="line"></span><br><span class="line">1. let 为变量，声明的字符串，类型为 string</span><br><span class="line">2. const 为常量，声明的字符串，类型为声明的对象名</span><br><span class="line">3. 除了字符串外，任意的JS字面量，都可作为类型使用</span><br><span class="line">4. 使用模式：`字面量类型配合联合类型一起使用`</span><br><span class="line">5. 使用场景：用来表示一组明确的可选值列表</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## typeof</span><br><span class="line"></span><br><span class="line">1. TS也提供了 typeof 操作符，可以在`类型上下文`中`引用变量或属性`的类型（类型查询）</span><br><span class="line">2. 使用场景：根据已有变量的值，获取该值的类型，来简化类型书写</span><br><span class="line">3. 解释：</span><br><span class="line">   1. 使用 `typeof `操作符来获取变量 P 的类型，结果与第一种（对象字面量形式的类型）相同</span><br><span class="line">   2. typeof 出现在`类型注解的位置`（参数名称的冒号后面）`所处的环境就在类型上下文`（区别于JS代码）</span><br><span class="line">   3. 注意：typeof 只能用来查询变量或属性的类型，无法查询其他形式的类型（比如，函数调用的类型）</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"># TS 高级类型</span><br><span class="line"></span><br><span class="line">1. TS 中的高级类型又很多，重点学习以下高级类型</span><br><span class="line">   1. class 类</span><br><span class="line">   2. 类型兼容</span><br><span class="line">   3. 交叉类型</span><br><span class="line">   4. 泛型 和 keyof</span><br><span class="line">   5. 索引签名类型 和 索引查询类型</span><br><span class="line">   6. 映射类型</span><br><span class="line"></span><br><span class="line">## Class 类</span><br><span class="line"></span><br><span class="line">1. TS 引入了 ES中的 `class `关键字，并为其添加了类型注解和其他语法（比如：可加性修饰符）</span><br><span class="line"></span><br><span class="line">2. 解释：</span><br><span class="line"></span><br><span class="line">   1. TS 中的 class ，不仅提供了 class 的语法功能，也作为一种类型存在</span><br><span class="line"></span><br><span class="line">3. 实例属性初始化</span><br><span class="line"></span><br><span class="line">   1. ```js</span><br><span class="line">      class Person&#123;</span><br><span class="line">          age:number 	// 方法一</span><br><span class="line">          gender=&#x27;男&#x27; // 方法二</span><br><span class="line">      &#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>解释：</p>
<ol>
<li>声明成员 age，类型为 number （没有初始值）</li>
<li>声明成员gender，并设置初始值，此时，可省略类型注解（TS 类型推论 ）</li>
</ol>
</li>
</ol>
</li>
</ol>
<h3 id="构造函数"><a href="#构造函数" class="headerlink" title="构造函数"></a>构造函数</h3><ol>
<li><p>关键字：constructor</p>
</li>
<li><p>实例</p>
<ol>
<li>```js<br>class Person{<pre><code>age:number
gender:string
constructor(age:number,gender:string)&#123;
    this.age = age
    this.gender = gender
&#125;
</code></pre>}<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">3. 解释：</span><br><span class="line"></span><br><span class="line">   1. 成员初始化（比如，age：number）后，才可以通过 this.age 来访问实例成员</span><br><span class="line">   2. 需要为构造函数指定类型注解，否则会被隐式推断为 any ；构造函数不需要返回值类型</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### 实例方法</span><br><span class="line"></span><br><span class="line">1. ```js</span><br><span class="line">   class Point&#123;</span><br><span class="line">       x = 10</span><br><span class="line">   	y = 10</span><br><span class="line">   	scale(n:number):void&#123;</span><br><span class="line">           this.x *=n</span><br><span class="line">           this.y *=n</span><br><span class="line">       &#125;</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure>
</li>
</ol>
</li>
<li><p>解释：方法的类型注解（参数和返回值）与函数用法相同</p>
</li>
</ol>
<h3 id="类的继承"><a href="#类的继承" class="headerlink" title="类的继承"></a>类的继承</h3><ol>
<li><p>类继承的两种方式：</p>
<ol>
<li>extends（继承父类）</li>
<li>implements（实现接口）</li>
</ol>
</li>
<li><p>说明：JS 中只有 extends，而 implements 是TS提供的</p>
</li>
<li><p>```js<br>class Animal {</p>
<pre><code>move()&#123; console.log(&#39;Moving along!&#39;) &#125;
</code></pre><p>}<br>class Dog extends Animal {</p>
<pre><code>bark() &#123; console.log(&#39;汪&#39;) &#125;
</code></pre><p>}<br>const dog = new Dog()</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">4. 解释：</span><br><span class="line"></span><br><span class="line">   1. 通过 `extends` 关键字实现`继承`</span><br><span class="line">   2. 子类 Dog 继承父类 Animal，则 Dog的实例 dog 就同时具有了父类 Animal 和 子类 Dog 的所有属性和方法</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### 实现接口</span><br><span class="line"></span><br><span class="line">1. 类的继承有两种方式：</span><br><span class="line"></span><br><span class="line">   1. extends（继承父类）</span><br><span class="line">   2. implements （实现接口）</span><br><span class="line"></span><br><span class="line">2. ```js</span><br><span class="line">   interface Singable&#123; // 定义接口</span><br><span class="line">       sing():void</span><br><span class="line">   &#125;</span><br><span class="line">   class Person implements Singable&#123; // 实现接口</span><br><span class="line">       sing()&#123;</span><br><span class="line">           console.log(&#x27;你是我的小苹果&#x27;)</span><br><span class="line">       &#125;</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>解析：</p>
<ol>
<li>通过 <code>implements</code>关键字让 class 实现接口</li>
<li>Person 类实现接口，Singable 意味着，Person 类中必须提供 Singable，接口中指定的所有方法和属性</li>
</ol>
</li>
</ol>
<h3 id="类成员的可见性"><a href="#类成员的可见性" class="headerlink" title="类成员的可见性"></a>类成员的可见性</h3><ol>
<li><p>类成员的可见性，可以使用 TS 来控制 class 的方法或属性对于 class 外的代码是否可见</p>
</li>
<li><p>和 C# 一样</p>
</li>
<li><p>可见性修饰符包括，</p>
<ol>
<li>public（公有的）</li>
<li>protected（受保护的）</li>
<li>private（私有的）</li>
</ol>
</li>
<li><p>public：表示公有的、公开的、<code>公有成员可被任何地方访问，默认可见性</code></p>
</li>
<li><p>```js<br>class Animal{</p>
<pre><code>public move()&#123;
    console.log(&#39;Moving along&#39;)
&#125;
</code></pre><p>}</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">6. 解释：在类属性或方法前面添加 `public `关键字，来修饰该属性或方法是公有的</span><br><span class="line"></span><br><span class="line">7. 因为 public 是默认可见性，所以，可以直接省略</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">### readonly（只读修饰符）</span><br><span class="line"></span><br><span class="line">1. 除了可见性修饰符外，还有一个常见的修饰符就是 readonly（只读修饰符）</span><br><span class="line"></span><br><span class="line">2. readonly：表示只读，用来防止在构造函数之外对属性进行赋值</span><br><span class="line"></span><br><span class="line">3. ```js</span><br><span class="line">   class Person&#123;</span><br><span class="line">       readonly age:number = 18</span><br><span class="line">   	constructor(age:number)</span><br><span class="line">   		this.age = age</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>解释：</p>
<ol>
<li>使用 <code>readonly</code> 关键字修饰该属性是只读的，注意：<code>只能修饰属性不能修饰方法</code></li>
<li>注意：<ol>
<li>属性age 后面的类型注解（比如，此处的 number）如果不加，则 age 的类型为 18 （字面量类型）</li>
<li>接口或者 {} 表示的对象类型，也可使用 readonly</li>
</ol>
</li>
</ol>
</li>
</ol>
<h2 id="类型兼容性"><a href="#类型兼容性" class="headerlink" title="类型兼容性"></a>类型兼容性</h2><h3 id="两种类型系统"><a href="#两种类型系统" class="headerlink" title="两种类型系统"></a>两种类型系统</h3><ol>
<li><p>两种类型系统：</p>
<ol>
<li>Structural Type System（结构化类型系统）</li>
<li>Nominal Type System（标明类型系统）</li>
</ol>
</li>
<li><p>TS采用的是结构化类型系统，也叫做 duck typing（鸭子类型），类型检查<code>关注的是值所具有的形状</code></p>
</li>
<li><p>也就是说，在结构类型系统中，如果两个对象具有<code>相同的形状，则认为他们属于同一类型</code></p>
</li>
<li><p>更准确的说：对于对象类型来说，成员多是可赋值给少的，则成员少的兼容成员多的，反之报错</p>
</li>
<li><p>例：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Point</span> &#123; <span class="attr">x</span>:number; <span class="attr">y</span>: number &#125;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Point2D</span> &#123; <span class="attr">x</span>:number; <span class="attr">y</span>: number; <span class="attr">Z</span>:string &#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="attr">p</span>:<span class="title class_">Point</span> = <span class="keyword">new</span> <span class="title class_">Poin2D</span>()</span><br><span class="line"><span class="comment">// Point 兼容 Point2D</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>除了class 之外，TS中的其他类型也存在相互兼容的情况，包括：</p>
<ol>
<li>接口兼容性</li>
<li>函数兼容性</li>
</ol>
</li>
</ol>
<h3 id="其他兼容性"><a href="#其他兼容性" class="headerlink" title="其他兼容性"></a>其他兼容性</h3><ol>
<li><code>接口之间的兼容性</code>，类似于 <code>class</code>，并且class和 interface 之间也可兼容</li>
<li><code>函数之间的兼容性</code>，需要考虑：<ol>
<li>参数个数，<code>参数多的兼容参数少的</code>或者说参数少的可赋值给多的</li>
<li>参数类型，<code>相同位置的参数类型要相同（原始类型）或兼容（对象类型）</code><ol>
<li>原始类型时，参数类型要保持一致</li>
<li>对象类型时，将对象拆开，把每个属性看做一个参数，则参数少的可赋值给参数多的</li>
</ol>
</li>
<li>返回值类型，只关注返回值类型本身即可<ol>
<li>如果返回值类型是原始类型，此时两个类型要相同</li>
<li>如果返回值类型是对象类型，此时成员多的可以赋值给成员少的</li>
</ol>
</li>
</ol>
</li>
</ol>
<h2 id="交叉类型"><a href="#交叉类型" class="headerlink" title="交叉类型"></a>交叉类型</h2><ol>
<li>交叉类型（&amp;）：功能类似于接口继承（extends），用于组合多个类型为一个类型（常用于对象类型）</li>
<li>交叉类型与接口继承的对比：<ol>
<li>相同点：<ol>
<li>都可以事项对象类型的组合</li>
</ol>
</li>
<li>不同点：<ol>
<li>两种方式实现类型组合时，对于同名属性之间，处理类型冲突的方式不同</li>
</ol>
</li>
</ol>
</li>
<li>在实际项目中要注意，类型兼容问题，特殊情况下接口继承会报错，交叉类型没错误，</li>
</ol>
<h2 id="泛型"><a href="#泛型" class="headerlink" title="泛型"></a>泛型</h2><ol>
<li>泛型是可以在<code>保证类型安全</code>前提下，让函数等<code>与多种类型一起工作</code>，从而<code>实现复用</code>，用于：<code>函数、接口、class</code>中</li>
</ol>
<h3 id="创建泛型"><a href="#创建泛型" class="headerlink" title="创建泛型"></a>创建泛型</h3><ol>
<li><p>创建泛型函数：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> id&lt;<span class="title class_">Type</span>&gt;(<span class="attr">value</span>:<span class="title class_">Type</span>):<span class="title class_">Type</span> &#123; <span class="keyword">return</span> value &#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>解释：</p>
<ol>
<li>语法：在函数名称的后面添加 <code>&lt;&gt;</code>（尖括号），<code>尖括号中添加类型变量</code>，比如 此处的 Type</li>
<li><code>类型变量</code> Type，<code>是一种特殊类型的变量，他处理类型</code>而不是值</li>
<li>该类型变量相当于一个类型容器，能够捕获用户提供的类型（具体是什么类型由用户调用该函数时指定）</li>
<li>因为 Type 是类型，因此可以将其作为函数参数和返回值的类型，表示参数和返回值具有相同的类型</li>
<li>类型是 Type，可以是任意合法的变量名称，<code>实现复用的同时保证类型安全</code></li>
</ol>
</li>
<li><p>例子：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 使用泛型来创建一个函数：</span></span><br><span class="line"><span class="keyword">function</span> id&lt;T&gt;(<span class="attr">value</span>: T): T &#123;</span><br><span class="line">  <span class="keyword">return</span> value</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 调用泛型函数</span></span><br><span class="line"><span class="comment">// 1.以number 类型调用泛型函数</span></span><br><span class="line"><span class="keyword">const</span> num = id&lt;number&gt;(<span class="number">10</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 2.以 string 类型 调用泛型函数</span></span><br><span class="line"><span class="keyword">const</span> str = id&lt;string&gt;(<span class="string">&#x27;1&#x27;</span>)</span><br></pre></td></tr></table></figure>
</li>
</ol>
<h3 id="简化调用泛型函数"><a href="#简化调用泛型函数" class="headerlink" title="简化调用泛型函数"></a>简化调用泛型函数</h3><ol>
<li><p>例子</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> id&lt;T&gt;(<span class="attr">value</span>: T): T &#123; <span class="keyword">return</span> value &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 简化调用泛型函数，两种写法效果一样</span></span><br><span class="line"><span class="keyword">let</span> num = id&lt;number&gt;(<span class="number">10</span>)</span><br><span class="line"><span class="keyword">let</span> num = <span class="title function_">id</span>(<span class="number">10</span>)</span><br></pre></td></tr></table></figure>
</li>
<li><p>解释：</p>
<ol>
<li>在调用泛型函数时，<code>可省略&lt;类型&gt;来简化泛型函数的调用</code></li>
<li>此时，TS 内部会采用<code>类型参数推断的机制</code>，来根据传入的实参自动推断出类型变量 Type 的类型</li>
</ol>
</li>
<li><p>说明：</p>
<ol>
<li>当编译器无法推断类型或者推断的类型不准确时，就需要显示地传入类型参数</li>
</ol>
</li>
</ol>
<h3 id="泛型约束"><a href="#泛型约束" class="headerlink" title="泛型约束"></a>泛型约束</h3><ol>
<li><p>默认情况下，泛型函数的类型变量Type 可以代表多个类型，这导致无法访问任何类型</p>
</li>
<li><p>比如：</p>
<ol>
<li><p>id（‘a’）调用函数时获取参数的长度</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> id&lt;<span class="title class_">Type</span>&gt;(value：<span class="title class_">Type</span>)：<span class="title class_">Type</span>&#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(value.<span class="property">length</span>)</span><br><span class="line">    <span class="keyword">return</span> value</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ol>
</li>
<li><p>解释：</p>
<ol>
<li>Type 可以代表任意类型，无法保证一定存在 length 属性，比如 number 类型就没有 length。</li>
<li>此时，就需要泛型<code>添加约束</code>来收缩类型（缩窄类型取值范围）</li>
</ol>
</li>
<li><p>添加泛型约束收缩类型，主要有以下两种方式</p>
<ol>
<li>指定更加具体的类型</li>
<li>添加约束<ol>
<li>创建描述约束的接口，该接口提供属性</li>
<li>通过 extends 关键字使用 该接口，为泛型（类型变量）添加约束</li>
<li>传入的值必须包含接口中定义的属性</li>
<li>有点像移花接木</li>
</ol>
</li>
</ol>
</li>
</ol>
<h3 id="类型变量之间还可以约束"><a href="#类型变量之间还可以约束" class="headerlink" title="类型变量之间还可以约束"></a>类型变量之间还可以约束</h3><ol>
<li><p>比如，第二个类型变量接受第一个类型变量约束</p>
</li>
<li><p>比如，创建一个函数来获取对象中属性的值</p>
</li>
<li><p>实例：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> getProp&lt;<span class="title class_">Type</span>,<span class="title class_">Key</span> <span class="keyword">extends</span> keyof <span class="title class_">Type</span>&gt;(<span class="attr">obj</span>:<span class="title class_">Type</span>，key：key)&#123;</span><br><span class="line">    <span class="keyword">return</span> obj[key]</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> person = &#123;<span class="attr">name</span>:<span class="string">&#x27;jack&#x27;</span>,<span class="attr">age</span>:<span class="number">18</span>&#125;</span><br><span class="line"><span class="title function_">getProp</span>(person,<span class="string">&#x27;name&#x27;</span>)</span><br></pre></td></tr></table></figure>
</li>
<li><p>解释：</p>
<ol>
<li>添加了第二个类型变量 key，两个类型变量之间使用（，）逗号分隔</li>
<li><code>keyof</code> 关键字<code>接收一个对象类型，生成其键名（可能是字符串或数字）的联合类型</code></li>
<li>本示例中 keyof Type 实际上获取的是 person 对象所有键的联合类型，也就是 ‘name’ | ‘age’</li>
<li>类型变量 key 受 Type 约束，可以理解为：key只能是 Type 所有键中的任意一个，或者说只能访问对象中存在的属性</li>
</ol>
</li>
</ol>
<h3 id="泛型接口"><a href="#泛型接口" class="headerlink" title="泛型接口"></a>泛型接口</h3><ol>
<li><p>泛型接口：接口也可以配合泛型来使用，以增加其灵活性，增加其复用性</p>
</li>
<li><p>实例：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> <span class="attr">obj</span>:<span class="title class_">IdFunc</span>&lt;number&gt; = &#123;</span><br><span class="line">    <span class="title function_">id</span>(<span class="params">value</span>)&#123; <span class="keyword">return</span> value &#125;,</span><br><span class="line">    <span class="title function_">ids</span>(<span class="params"></span>)&#123; <span class="keyword">return</span> [<span class="number">1</span>,<span class="number">3</span>,<span class="number">5</span>] &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>解释：</p>
<ol>
<li>在接口名称后面添加<code>&lt;类型变量&gt;</code>，那么，这个接口就变成了泛型接口</li>
<li>接口的类型变量，对接口中所有其他成员可见，也就是<code>接口中所有成员都可以使用接口类型变量</code></li>
<li>使用泛型接口，<code>需要显示指定</code>具体的<code>类型</code>（比如，此处的 IdFunc<number>）</li>
<li>此时，id方法的参数和返回值类型都是 number；ids方法的返回值类型是 number[]</li>
</ol>
</li>
<li><p>实际上，JS 中的数组在TS中就是一个泛型接口</p>
</li>
<li><p>解释：</p>
<ol>
<li>当我们在使用数组时，TS会根据数组的不同类型，来自动将类型变量设置为相应的类型</li>
</ol>
</li>
<li><p>技巧：</p>
<ol>
<li>可以通过 Ctrl + 鼠标左键（Mac：option +鼠标左键）来查看具体的类型信息</li>
</ol>
</li>
</ol>
<h3 id="泛型类"><a href="#泛型类" class="headerlink" title="泛型类"></a>泛型类</h3><ol>
<li>泛型类：class 也可配合泛型来使用</li>
<li>比如：React 的class 组件的基类 Component 就是泛型类，不同的组件有不同的 Props 和 State</li>
<li>解释：<ol>
<li>React.Component 泛型类两个类型变量，分别指定 proos 和 state 类型</li>
</ol>
</li>
</ol>
<h3 id="泛型工具类型"><a href="#泛型工具类型" class="headerlink" title="泛型工具类型"></a>泛型工具类型</h3><ol>
<li>TS 内置了一些常用的<code>工具类型</code>，来简化 TS 中的一些常见的操作</li>
<li>说明：他们都是<code>基于泛型实现的</code>（泛型使用于多种类型，更加通用），并且是内置的，可以直接在代码中使用</li>
<li>主要学习以下几个<ol>
<li>Partial<Type></li>
<li>Readonly/<Type></li>
<li>Pick<Type,key></li>
<li>Record<Keys,Type></li>
</ol>
</li>
</ol>
<h4 id="Partial"><a href="#Partial" class="headerlink" title="Partial"></a>Partial<Type></h4><ol>
<li><p>用来构造（创建）一个类型，将 Type 的<code>所有属性设置为可选</code></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">interface <span class="title class_">Props</span>&#123;</span><br><span class="line">    <span class="attr">id</span>:string</span><br><span class="line">    <span class="attr">children</span>:number[]</span><br><span class="line">&#125;</span><br><span class="line">type <span class="title class_">PartialProps</span> = <span class="title class_">Partial</span>&lt;<span class="title class_">Props</span>&gt;</span><br></pre></td></tr></table></figure>
</li>
<li><p>解释：构造出来的新类型 PartialProps 结构和 Props 相同，但<code>所有属性都变为可选的</code></p>
</li>
</ol>
<h4 id="Readonly"><a href="#Readonly" class="headerlink" title="Readonly/"></a>Readonly/<Type></h4><ol>
<li><p>用来构造一个类型，将 Type 的所有属性都设置为 readonly（只读）</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">interface <span class="title class_">Props</span>&#123;</span><br><span class="line">    <span class="attr">id</span>:string</span><br><span class="line">    <span class="attr">children</span>:number[]</span><br><span class="line">&#125;</span><br><span class="line">type <span class="title class_">PartialProps</span> = <span class="title class_">Readonly</span>&lt;<span class="title class_">Props</span>&gt;</span><br></pre></td></tr></table></figure>
</li>
<li><p>解释：</p>
<ol>
<li>构造出来的新类型 ReadonlyProps 结构和 Props 相同，<code>但所有属性都变为只读的</code></li>
</ol>
</li>
<li><p>当我们想重新给 id 属性赋值时，就会报错：无法分配到 ‘id’，因为他是只读属性</p>
</li>
</ol>
<h4 id="Pick"><a href="#Pick" class="headerlink" title="Pick"></a>Pick<Type,key></h4><ol>
<li><p>Pick<Type,key>从Type 中选择一组属性来构造成新类型</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">interface <span class="title class_">Props</span>&#123;</span><br><span class="line">    <span class="attr">id</span>:string</span><br><span class="line">    <span class="attr">title</span>:string</span><br><span class="line">    <span class="attr">children</span>:number[]</span><br><span class="line">&#125;</span><br><span class="line">type <span class="title class_">PickProps</span> = <span class="title class_">Pick</span>&lt;<span class="title class_">Props</span>,<span class="string">&#x27;id&#x27;</span>|<span class="string">&#x27;title&#x27;</span>&gt;</span><br></pre></td></tr></table></figure>
</li>
<li><p>解释：</p>
<ol>
<li>Pick 工具类型有两个类型变量：<ol>
<li>表示选择谁的属性</li>
<li>表示选择哪几个属性</li>
</ol>
</li>
<li>其中第二个类型变量，如果只选择一个则只传入该属性名即可</li>
<li><code>第二个类型变量传入的属性只能是第一个类型变量中存在的属性</code></li>
<li>构造出来的新类型PickProps，只有 id 和 title 两个属性类型</li>
</ol>
</li>
</ol>
<h4 id="Record"><a href="#Record" class="headerlink" title="Record"></a>Record<Keys,Type></h4><ol>
<li><p>构造一个对象类型，属性键为 Keys，属性类型为 Type，可以保证类型都是相同的</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">type <span class="title class_">RecordObj</span> = <span class="title class_">Record</span>&lt;<span class="string">&#x27;a&#x27;</span>|<span class="string">&#x27;b&#x27;</span>|<span class="string">&#x27;c&#x27;</span>,string[]&gt;</span><br><span class="line"><span class="keyword">let</span> <span class="attr">obj</span>:<span class="title class_">RecordObj</span> = &#123;</span><br><span class="line">    <span class="attr">a</span>:[<span class="string">&#x27;1&#x27;</span>],</span><br><span class="line">    <span class="attr">b</span>:[<span class="string">&#x27;2&#x27;</span>],</span><br><span class="line">    <span class="attr">c</span>:[<span class="string">&#x27;3&#x27;</span>]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>解释：</p>
<ol>
<li>Record 工具类型有两个类型的变量：<ol>
<li>表示对象有哪些属性</li>
<li>表示对象属性的类型</li>
</ol>
</li>
<li>构建的新对象类型RecordObj 表示：这个对象有三个属性分别是 a/b/c，属性值的类型都是 string[]</li>
</ol>
</li>
</ol>
<h2 id="索引类型签名"><a href="#索引类型签名" class="headerlink" title="索引类型签名"></a>索引类型签名</h2><ol>
<li><p>绝大多数情况下，我们都可以在使用对象前就确定对象的结构，并为对象添加准确的类型</p>
</li>
<li><p>使用场景：<code>当无法确定对象中有哪些属性</code>（或者说对象中可以出现任意多个属性），此时，就用到<code>索引签名类型</code>了</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">interface <span class="title class_">AnyObject</span> &#123;</span><br><span class="line">    [<span class="attr">key</span>:string]:number</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ol>
<ol>
<li><p>解释：</p>
<ol>
<li>使用<code>[key：string]</code>来约束该接口中允许出现的属性名称，表示只要是 string 类型的属性名称，都可以出现在对象中</li>
<li>这样，对象 obj 中就可以出现任意多个属性（比如，a，b等）</li>
<li><code>key 只是一个占位符</code>，可以换成任意合法的变量名称</li>
<li>隐藏的前置知识：<code>JS中对象（&#123;&#125;）的键是 string 类型的</code></li>
</ol>
</li>
</ol>
<h3 id="数值类型"><a href="#数值类型" class="headerlink" title="数值类型"></a>数值类型</h3><ol>
<li><p>在 JS 中数值是一类特殊的对象，特殊在数组的键（索引）是数值类型</p>
</li>
<li><p>并且，数组也可以出现任意多个元素。所以，在数组对应的泛型接口中，也用到了索引签名类型</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">interface <span class="title class_">MyArray</span>&lt;T&gt;&#123;</span><br><span class="line">    [<span class="attr">n</span>:number]:T</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> <span class="attr">arr</span>:<span class="title class_">MyArray</span>&lt;number&gt; = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]</span><br></pre></td></tr></table></figure>
</li>
<li><p>解释：</p>
<ol>
<li>MyArray 接口模拟原生的数组接口，并使用 <code>[n:number]</code> 来作为索引签名类型</li>
<li>该索引签名类型表示：只要是number 类型的键（索引都可以出现在数组中，或者说数组中可以有任意多个元素）</li>
<li>同时也符合数组索引是 number 类型者一前提</li>
</ol>
</li>
</ol>
<h2 id="映射类型"><a href="#映射类型" class="headerlink" title="映射类型"></a>映射类型</h2><ol>
<li><p>映射类型：<code>基于旧类型创建新类型（对象类型）</code>，减少重复，提升开发效率</p>
</li>
<li><p>可以使用 联合类型或对象类型来创建 映射类型</p>
</li>
<li><p>联合类型：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">type <span class="title class_">PropKeys</span> = <span class="string">&#x27;x&#x27;</span> | <span class="string">&#x27;y&#x27;</span> | <span class="string">&#x27;z&#x27;</span></span><br><span class="line">type <span class="title class_">Type2</span> = &#123; [key <span class="keyword">in</span> <span class="title class_">PropKeys</span>]:number &#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>解释：</p>
<ol>
<li>映射类型是基于索引签名类型的，所以，该语法类似于索引签名类型，也使用了 []</li>
<li><code>key in Propkeys</code> 表示 key 可以是 Propkeys 联合类型中的任意一个，类似于 forin(let k in obj)</li>
<li>使用映射类型创建的新对象类型 Type2 和类型 Type1 结构完全相同</li>
<li>注意：<ol>
<li>映射类型<code>只能在类型别名中使用</code>，不能在接口中使用</li>
</ol>
</li>
</ol>
</li>
<li><p>对象类型：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">type <span class="title class_">Props</span> = &#123;<span class="attr">a</span>:number; <span class="attr">b</span>:string; <span class="attr">c</span>:boolean&#125;</span><br><span class="line">type <span class="title class_">Type</span> = &#123; [key <span class="keyword">in</span> keyof <span class="title class_">Props</span>]:number &#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>解释：</p>
<ol>
<li>首先，先执行了 keyof  Props 获取对象类型 Props 中所有键的联合类型即：‘a’ | ‘b’ | ‘c’</li>
<li>然后，key in… 就表示 key 可以是 Props 中所有的键名称中的任意一个</li>
</ol>
</li>
<li><p>语法T[P] ，在TS 中叫做索引查询（访问）类型</p>
</li>
<li><p>作用：用来查询属性的类型</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">type <span class="title class_">Props</span> = &#123;<span class="attr">a</span>:number; <span class="attr">b</span>:string; <span class="attr">c</span>:boolean&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>解释：</p>
<ol>
<li>Props[‘a’] 表示查询类型 Props 中属性 ‘a’ 对应的类型 number，所以，TypeA 的类型为 number</li>
</ol>
</li>
<li><p>注意：</p>
<ol>
<li>[ ] 中的属性必须存在于被查询类型中，否则就会报错</li>
</ol>
</li>
</ol>
<h1 id="TS-类型声明文件"><a href="#TS-类型声明文件" class="headerlink" title="TS 类型声明文件"></a>TS 类型声明文件</h1><ol>
<li>类型声明文件：用来为已存在的 JS 库 提供类型信息</li>
<li>这样在 TS 项目中使用这些库时，就像用 TS 一样，都会有代码提示，类型保护等机制了</li>
<li>TS 两种文件类型<ol>
<li>普通的TS文件</li>
<li>d.ts 文件</li>
</ol>
</li>
<li>类型声明文件的使用说明</li>
</ol>
<h2 id="TS-中两种文件类型"><a href="#TS-中两种文件类型" class="headerlink" title="TS 中两种文件类型"></a>TS 中两种文件类型</h2><ol>
<li>TS 中有两个文件类型：<ol>
<li>.ts 文件</li>
<li>.d.ts 文件</li>
</ol>
</li>
<li>.ts 文件：<ol>
<li>既包含类型信息又可执行代码</li>
<li>可以被编译为 .js 文件，然后执行代码</li>
<li>用途：编写程序代码的地方</li>
</ol>
</li>
<li>.d.ts 文件：<ol>
<li>只包含类型信息的类型声明文件</li>
<li>不会生成 .js 文件，仅用于提供类型信息</li>
<li>用途：为 js 提供类型信息</li>
</ol>
</li>
<li>总结：<ol>
<li>.ts 是implementation（代码实现文件）；</li>
<li>.d.ts 是declaration（类型声明文件）</li>
<li>如果要为 js 库提供类型信息，要使用 .d.ts 文件</li>
</ol>
</li>
</ol>
<h2 id="类型声明文件的使用说明"><a href="#类型声明文件的使用说明" class="headerlink" title="类型声明文件的使用说明"></a>类型声明文件的使用说明</h2><ol>
<li>在使用 TS 开发项目时，类型声明文件的使用包括以下两种方式</li>
<li>使用已有的类型声明文件</li>
<li>创建自己的类型声明文件</li>
<li>学习顺序：先会用（别人的）再会写（自己的）</li>
</ol>
<h3 id="使用已有的类型声明文件"><a href="#使用已有的类型声明文件" class="headerlink" title="使用已有的类型声明文件"></a>使用已有的类型声明文件</h3><ol>
<li>使用已有的类型声明文件：<ol>
<li>内置类型声明文件</li>
<li>第三方库的类型声明文件</li>
</ol>
</li>
<li>内置类型声明文件：<ol>
<li>TS为 JS 运行时可用的所有标准化内置API都 提供了声明文件</li>
<li>比如：在使用数组时，数组所有方法都会有相应的代码提示以及类型信息</li>
<li>实际上这些都是 TS 提供的内置类型声明文件</li>
<li>可以通过 Ctrl + 鼠标左键来查看内置类型的声明文件</li>
</ol>
</li>
<li>第三方库的类型声明文件：<ol>
<li>目前，几乎所有常用的第三方库都有相应的类型声明文件</li>
<li>第三方库的类型声明文件存在两种方式：<ol>
<li>库自带类型声明文件 <code>.d.ts</code> 文件，这中情况下<code>TS就会自动加载库自己的类型声明文件</code>，以提供该库的类型声明</li>
<li>有 DefinitelyTyped 提供</li>
</ol>
</li>
<li>库自带类型声明文件<ol>
<li><code>.d.ts</code> 文件，这中情况下<code>TS就会自动加载库自己的类型声明文件</code>，以提供该库的类型声明</li>
<li>在 package.json 中 typings：属性可以指定加载的库类型声明文件</li>
</ol>
</li>
<li>有 DefinitelyType 提供：<ol>
<li>DefinitelyTyped 是一个GitHub仓库，用来提供高质量 TS 类型声明</li>
<li>可以通过 npm/yarn 来下载该仓库提供的 TS 类型声明包，这些包的名称格式为：@types/*</li>
<li>比如，@type/react、@type/lodash 等</li>
<li>解释：<ol>
<li>当安装 @type/* 类型声明包后，TS 也会自动加载该类型声明包，以提供该库的类型声明</li>
<li>可借鉴TS 官方文档提供的页面，来查询 @type/* 库</li>
</ol>
</li>
<li>小技巧：<ol>
<li>在TS 文件中，导入 第三方包，包名会有三个点，鼠标放上去，会提示有隐式的any类型，可用 npm… 来下载 类型声明文件库，下载后就能用了</li>
<li>前提，得先有包才能导入类型声明文件</li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
</ol>
<h3 id="创建自己的类型声明文件"><a href="#创建自己的类型声明文件" class="headerlink" title="创建自己的类型声明文件"></a>创建自己的类型声明文件</h3><ol>
<li><p>创建自己的类型声明文件：</p>
<ol>
<li>项目内共享类型</li>
<li>为已有的 JS 文件提供类型声明</li>
</ol>
</li>
<li><p>项目共享类型：</p>
<ol>
<li>如果多个 .ts 文件中都用到同一类型，此时可创建 .d.ts 文件提供该类型，实现类型共享</li>
</ol>
</li>
<li><p>操作步骤：</p>
<ol>
<li>创建 index.d.ts 类型声明的文件</li>
<li>创建需要共享的类型，并使用 export 导出，（TS 中的类型也可使用 import/export 实现模块化功能 ）</li>
<li>在需要使用共享类型的 .ts 文件中，通过 import 导入即可（.d.ts 后缀导入时，直接省略）</li>
</ol>
</li>
<li><p>类似于，在第三方文件中声明TS类型并导出，用来控制使用的类型，使用时引入即可，后缀为 .d.ts</p>
<figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 管理类型，类型声明文件   index.d.ts 文件</span></span><br><span class="line"><span class="keyword">type</span> <span class="title class_">Props</span> = &#123; <span class="attr">x</span>: <span class="built_in">number</span>; <span class="attr">y</span>: <span class="built_in">number</span> &#125;</span><br><span class="line"><span class="keyword">export</span> &#123; <span class="title class_">Props</span> &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// a.ts 文件引入</span></span><br><span class="line"><span class="keyword">import</span> &#123; <span class="title class_">Props</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;./index&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用,直接引用即可</span></span><br><span class="line"><span class="keyword">let</span> <span class="attr">p1</span>: <span class="title class_">Props</span> = &#123;</span><br><span class="line">  <span class="attr">x</span>: <span class="number">1</span>,</span><br><span class="line">  <span class="attr">y</span>: <span class="number">2</span>,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
</ol>
<p>5.</p>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="http://example.com">晚夜微雨问海棠</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="http://example.com/posts/d044eab7.html">http://example.com/posts/d044eab7.html</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="http://example.com" target="_blank">晚夜微雨问海棠のBlog</a>！</span></div></div><div class="tag_share"><div class="post_share"><div class="social-share" data-image="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fwww.linuxeden.com%2Fwp-content%2Fuploads%2F2018%2F07%2F4d61b0d3264e651fde2e5a07d856381323d.jpg&amp;refer=http%3A%2F%2Fwww.linuxeden.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1664441895&amp;t=eeff26717d91ad1e5d6930cd5f9867b7" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><div class="post-reward"><div class="reward-button"><i class="fas fa-qrcode"></i> 打赏</div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="https://s1.ax1x.com/2022/11/15/zE9P7d.jpg" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="https://s1.ax1x.com/2022/11/15/zE9P7d.jpg" alt="微信"/></a><div class="post-qr-code-desc">微信</div></li><li class="reward-item"><a href="https://s1.ax1x.com/2022/11/15/zE9ung.jpg" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="https://s1.ax1x.com/2022/11/15/zE9ung.jpg" alt="支付宝"/></a><div class="post-qr-code-desc">支付宝</div></li></ul></div></div><hr/><div id="post-comment"><div class="comment-head"><div class="comment-headline"><i class="fas fa-comments fa-fw"></i><span> 评论</span></div></div><div class="comment-wrap"><div><div class="vcomment" id="vcomment"></div></div></div></div></div><div class="aside-content" id="aside-content"><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content is-expand"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#TypeScript-%E4%BB%8B%E7%BB%8D"><span class="toc-number">1.</span> <span class="toc-text">TypeScript 介绍</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#Typescript-%E5%AE%89%E8%A3%85-%E7%BC%96%E8%AF%91"><span class="toc-number">1.1.</span> <span class="toc-text">Typescript 安装 编译</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%B8%83%E5%B0%94%E7%B1%BB%E5%9E%8B%EF%BC%88boolean%EF%BC%89"><span class="toc-number">1.2.</span> <span class="toc-text">布尔类型（boolean）</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%95%B0%E5%AD%97%E7%B1%BB%E5%9E%8B-%EF%BC%88number%EF%BC%89"><span class="toc-number">1.3.</span> <span class="toc-text">数字类型 （number）</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%B1%BB%E5%9E%8B%EF%BC%88string%EF%BC%89"><span class="toc-number">1.4.</span> <span class="toc-text">字符串类型（string）</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%95%B0%E7%BB%84%E7%B1%BB%E5%9E%8B-%EF%BC%88array%EF%BC%89"><span class="toc-number">1.5.</span> <span class="toc-text">数组类型 （array）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%AC%AC%E4%B8%80%E7%A7%8D%E6%96%B9%E5%BC%8F%EF%BC%9A%E5%8F%AA%E8%83%BD%E5%86%99%E5%AF%B9%E5%BA%94%E7%9A%84%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%80%BC"><span class="toc-number">1.5.1.</span> <span class="toc-text">第一种方式：只能写对应的类型的值</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%AC%AC%E4%BA%8C%E7%A7%8D%E6%96%B9%E5%BC%8F%EF%BC%9A%E6%B3%9B%E5%9E%8B-%E5%90%8C%E6%A0%B7%E5%8F%AA%E8%83%BD%E5%86%99%E5%AF%B9%E5%BA%94%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%80%BC"><span class="toc-number">1.5.2.</span> <span class="toc-text">第二种方式：泛型,同样只能写对应类型的值</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%AC%AC%E4%B8%89%E7%A7%8D%E6%96%B9%E5%BC%8F%EF%BC%9A%E4%BD%BF%E7%94%A8-any-%E7%B1%BB%E5%9E%8B%EF%BC%8C%E5%8F%AF%E5%86%99%E4%BB%BB%E6%84%8F%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%80%BC"><span class="toc-number">1.5.3.</span> <span class="toc-text">第三种方式：使用 any 类型，可写任意类型的值</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%83%E7%BB%84%E7%B1%BB%E5%9E%8B%EF%BC%88tuple%EF%BC%89"><span class="toc-number">1.6.</span> <span class="toc-text">元组类型（tuple）</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%BB%E6%84%8F%E7%B1%BB%E5%9E%8B%EF%BC%88any%EF%BC%89"><span class="toc-number">1.7.</span> <span class="toc-text">任意类型（any）</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#null-%E5%92%8C-undefined"><span class="toc-number">1.8.</span> <span class="toc-text">null 和 undefined</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#void%E7%B1%BB%E5%9E%8B"><span class="toc-number">1.9.</span> <span class="toc-text">void类型</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#never%E7%B1%BB%E5%9E%8B"><span class="toc-number">1.10.</span> <span class="toc-text">never类型</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E7%B1%BB%E5%9E%8B"><span class="toc-number">1.11.</span> <span class="toc-text">函数类型</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AF%B9%E8%B1%A1%E7%B1%BB%E5%9E%8B"><span class="toc-number">1.12.</span> <span class="toc-text">对象类型</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%B1%BB%E5%9E%8B%E5%88%AB%E5%90%8D"><span class="toc-number">1.13.</span> <span class="toc-text">类型别名</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80"><span class="toc-number">1.14.</span> <span class="toc-text">类型断言</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0"><span class="toc-number">1.14.1.</span> <span class="toc-text">构造函数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B1%BB%E7%9A%84%E7%BB%A7%E6%89%BF"><span class="toc-number">1.14.2.</span> <span class="toc-text">类的继承</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B1%BB%E6%88%90%E5%91%98%E7%9A%84%E5%8F%AF%E8%A7%81%E6%80%A7"><span class="toc-number">1.14.3.</span> <span class="toc-text">类成员的可见性</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%B1%BB%E5%9E%8B%E5%85%BC%E5%AE%B9%E6%80%A7"><span class="toc-number">1.15.</span> <span class="toc-text">类型兼容性</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B8%A4%E7%A7%8D%E7%B1%BB%E5%9E%8B%E7%B3%BB%E7%BB%9F"><span class="toc-number">1.15.1.</span> <span class="toc-text">两种类型系统</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%B6%E4%BB%96%E5%85%BC%E5%AE%B9%E6%80%A7"><span class="toc-number">1.15.2.</span> <span class="toc-text">其他兼容性</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BA%A4%E5%8F%89%E7%B1%BB%E5%9E%8B"><span class="toc-number">1.16.</span> <span class="toc-text">交叉类型</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%B3%9B%E5%9E%8B"><span class="toc-number">1.17.</span> <span class="toc-text">泛型</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%88%9B%E5%BB%BA%E6%B3%9B%E5%9E%8B"><span class="toc-number">1.17.1.</span> <span class="toc-text">创建泛型</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%AE%80%E5%8C%96%E8%B0%83%E7%94%A8%E6%B3%9B%E5%9E%8B%E5%87%BD%E6%95%B0"><span class="toc-number">1.17.2.</span> <span class="toc-text">简化调用泛型函数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%B3%9B%E5%9E%8B%E7%BA%A6%E6%9D%9F"><span class="toc-number">1.17.3.</span> <span class="toc-text">泛型约束</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%B1%BB%E5%9E%8B%E5%8F%98%E9%87%8F%E4%B9%8B%E9%97%B4%E8%BF%98%E5%8F%AF%E4%BB%A5%E7%BA%A6%E6%9D%9F"><span class="toc-number">1.17.4.</span> <span class="toc-text">类型变量之间还可以约束</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%B3%9B%E5%9E%8B%E6%8E%A5%E5%8F%A3"><span class="toc-number">1.17.5.</span> <span class="toc-text">泛型接口</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%B3%9B%E5%9E%8B%E7%B1%BB"><span class="toc-number">1.17.6.</span> <span class="toc-text">泛型类</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%B3%9B%E5%9E%8B%E5%B7%A5%E5%85%B7%E7%B1%BB%E5%9E%8B"><span class="toc-number">1.17.7.</span> <span class="toc-text">泛型工具类型</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#Partial"><span class="toc-number">1.17.7.1.</span> <span class="toc-text">Partial</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Readonly"><span class="toc-number">1.17.7.2.</span> <span class="toc-text">Readonly&#x2F;</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Pick"><span class="toc-number">1.17.7.3.</span> <span class="toc-text">Pick</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Record"><span class="toc-number">1.17.7.4.</span> <span class="toc-text">Record</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%B4%A2%E5%BC%95%E7%B1%BB%E5%9E%8B%E7%AD%BE%E5%90%8D"><span class="toc-number">1.18.</span> <span class="toc-text">索引类型签名</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%95%B0%E5%80%BC%E7%B1%BB%E5%9E%8B"><span class="toc-number">1.18.1.</span> <span class="toc-text">数值类型</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%98%A0%E5%B0%84%E7%B1%BB%E5%9E%8B"><span class="toc-number">1.19.</span> <span class="toc-text">映射类型</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#TS-%E7%B1%BB%E5%9E%8B%E5%A3%B0%E6%98%8E%E6%96%87%E4%BB%B6"><span class="toc-number">2.</span> <span class="toc-text">TS 类型声明文件</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#TS-%E4%B8%AD%E4%B8%A4%E7%A7%8D%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B"><span class="toc-number">2.1.</span> <span class="toc-text">TS 中两种文件类型</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%B1%BB%E5%9E%8B%E5%A3%B0%E6%98%8E%E6%96%87%E4%BB%B6%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E"><span class="toc-number">2.2.</span> <span class="toc-text">类型声明文件的使用说明</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8%E5%B7%B2%E6%9C%89%E7%9A%84%E7%B1%BB%E5%9E%8B%E5%A3%B0%E6%98%8E%E6%96%87%E4%BB%B6"><span class="toc-number">2.2.1.</span> <span class="toc-text">使用已有的类型声明文件</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%88%9B%E5%BB%BA%E8%87%AA%E5%B7%B1%E7%9A%84%E7%B1%BB%E5%9E%8B%E5%A3%B0%E6%98%8E%E6%96%87%E4%BB%B6"><span class="toc-number">2.2.2.</span> <span class="toc-text">创建自己的类型声明文件</span></a></li></ol></li></ol></li></ol></div></div></div></div></main><footer id="footer" style="background-image: url('https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fwww.linuxeden.com%2Fwp-content%2Fuploads%2F2018%2F07%2F4d61b0d3264e651fde2e5a07d856381323d.jpg&amp;refer=http%3A%2F%2Fwww.linuxeden.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1664441895&amp;t=eeff26717d91ad1e5d6930cd5f9867b7')"><div id="footer-wrap"><div class="copyright">&copy;2022 - 2023 By 晚夜微雨问海棠</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="translateLink" type="button" title="简繁转换">繁</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="chat_btn" type="button" title="聊天"><i class="fas fa-sms"></i></button><a id="to_comment" href="#post-comment" title="直达评论"><i class="fas fa-comments"></i></a><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span>  数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><hr/><div id="local-search-results"></div></div></div><div id="search-mask"></div></div><div id="rightMenu"><div class="rightMenu-group rightMenu-small"><div class="rightMenu-item" id="menu-backward"><i class="fa-solid fa-arrow-left"></i></div><div class="rightMenu-item" id="menu-forward"><i class="fa-solid fa-arrow-right"></i></div><div class="rightMenu-item" id="menu-refresh"><i class="fa-solid fa-arrow-rotate-right"></i></div><div class="rightMenu-item" id="menu-home"><i class="fa-solid fa-house"></i></div></div><div class="rightMenu-group rightMenu-line rightMenuOther"><a class="rightMenu-item menu-link" href="/archives/"><i class="fa-solid fa-archive"></i><span>文章归档</span></a><a class="rightMenu-item menu-link" href="/categories/"><i class="fa-solid fa-folder-open"></i><span>文章分类</span></a><a class="rightMenu-item menu-link" href="/tags/"><i class="fa-solid fa-tags"></i><span>文章标签</span></a></div><div class="rightMenu-group rightMenu-line rightMenuNormal"><div class="rightMenu-item" id="menu-translate"><i class="fa-solid fa-earth-asia"></i><span>繁简切换</span></div><div class="rightMenu-item" id="menu-darkmode"><i class="fa-solid fa-moon"></i><span>切换模式</span></div></div></div><div id="rightmenu-mask"></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="/js/tw_cn.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.umd.min.js"></script><script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><script src="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.js"></script><script src="/js/search/local-search.js"></script><script>var preloader = {
  endLoading: () => {
    document.body.style.overflow = 'auto';
    document.getElementById('loading-box').classList.add("loaded")
  },
  initLoading: () => {
    document.body.style.overflow = '';
    document.getElementById('loading-box').classList.remove("loaded")

  }
}
window.addEventListener('load',preloader.endLoading())</script><div class="js-pjax"><script>(() => {
  const $mermaidWrap = document.querySelectorAll('#article-container .mermaid-wrap')
  if ($mermaidWrap.length) {
    window.runMermaid = () => {
      window.loadMermaid = true
      const theme = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'default'

      Array.from($mermaidWrap).forEach((item, index) => {
        const mermaidSrc = item.firstElementChild
        const mermaidThemeConfig = '%%{init:{ \'theme\':\'' + theme + '\'}}%%\n'
        const mermaidID = 'mermaid-' + index
        const mermaidDefinition = mermaidThemeConfig + mermaidSrc.textContent
        mermaid.mermaidAPI.render(mermaidID, mermaidDefinition, (svgCode) => {
          mermaidSrc.insertAdjacentHTML('afterend', svgCode)
        })
      })
    }

    const loadMermaid = () => {
      window.loadMermaid ? runMermaid() : getScript('https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js').then(runMermaid)
    }

    window.pjax ? loadMermaid() : document.addEventListener('DOMContentLoaded', loadMermaid)
  }
})()</script><script>function loadValine () {
  function initValine () {
    const valine = new Valine(Object.assign({
      el: '#vcomment',
      appId: '',
      appKey: '',
      avatar: 'monsterid',
      serverURLs: '',
      emojiMaps: "",
      path: window.location.pathname,
      visitor: false
    }, null))
  }

  if (typeof Valine === 'function') initValine() 
  else getScript('https://cdn.jsdelivr.net/npm/valine/dist/Valine.min.js').then(initValine)
}

if ('Valine' === 'Valine' || !true) {
  if (true) btf.loadComment(document.getElementById('vcomment'),loadValine)
  else setTimeout(loadValine, 0)
} else {
  function loadOtherComment () {
    loadValine()
  }
}</script></div><div class="aplayer no-destroy" data-id="7625372994" data-server="netease" data-type="playlist" data-fixed="true" data-autoplay="true"> </div> <script defer src="https://npm.elemecdn.com/jquery@latest/dist/jquery.min.js"></script> <script src="/swiper/swiper.min.js"></script> <script src="/swiper/swiperindex.js"></script> <script src="//cdn.bootcss.com/pace/1.0.2/pace.min.js"></script> <script src="/js/title.js"></script> <script defer data-pjax src="/js/cat.js"></script> <script defer data-pjax src="/js/rightMenu.js"></script><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/activate-power-mode.min.js"></script><script>POWERMODE.colorful = true;
POWERMODE.shake = false;
POWERMODE.mobile = false;
document.body.addEventListener('input', POWERMODE);
</script><script id="click-heart" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/click-heart.min.js" async="async" mobile="false"></script><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/metingjs/dist/Meting.min.js"></script><script src="https://cdn.jsdelivr.net/npm/pjax/pjax.min.js"></script><script>let pjaxSelectors = ["head > title","#config-diff","#body-wrap","#rightside-config-hide","#rightside-config-show","#web_bg",".js-pjax"]

var pjax = new Pjax({
  elements: 'a:not([target="_blank"])',
  selectors: pjaxSelectors,
  cacheBust: false,
  analytics: false,
  scrollRestoration: false
})

document.addEventListener('pjax:send', function () {

  // removeEventListener scroll 
  window.tocScrollFn && window.removeEventListener('scroll', window.tocScrollFn)
  window.scrollCollect && window.removeEventListener('scroll', scrollCollect)

  typeof preloader === 'object' && preloader.initLoading()
  document.getElementById('rightside').style.cssText = "opacity: ''; transform: ''"
  
  if (window.aplayers) {
    for (let i = 0; i < window.aplayers.length; i++) {
      if (!window.aplayers[i].options.fixed) {
        window.aplayers[i].destroy()
      }
    }
  }

  typeof typed === 'object' && typed.destroy()

  //reset readmode
  const $bodyClassList = document.body.classList
  $bodyClassList.contains('read-mode') && $bodyClassList.remove('read-mode')

  typeof disqusjs === 'object' && disqusjs.destroy()
})

document.addEventListener('pjax:complete', function () {
  window.refreshFn()

  document.querySelectorAll('script[data-pjax]').forEach(item => {
    const newScript = document.createElement('script')
    const content = item.text || item.textContent || item.innerHTML || ""
    Array.from(item.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value))
    newScript.appendChild(document.createTextNode(content))
    item.parentNode.replaceChild(newScript, item)
  })

  GLOBAL_CONFIG.islazyload && window.lazyLoadInstance.update()

  typeof chatBtnFn === 'function' && chatBtnFn()
  typeof panguInit === 'function' && panguInit()

  // google analytics
  typeof gtag === 'function' && gtag('config', '', {'page_path': window.location.pathname});

  // baidu analytics
  typeof _hmt === 'object' && _hmt.push(['_trackPageview',window.location.pathname]);

  typeof loadMeting === 'function' && document.getElementsByClassName('aplayer').length && loadMeting()

  // prismjs
  typeof Prism === 'object' && Prism.highlightAll()

  typeof preloader === 'object' && preloader.endLoading()
})

document.addEventListener('pjax:error', (e) => {
  if (e.request.status === 404) {
    pjax.loadUrl('/404.html')
  }
})</script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div><!-- hexo injector body_end start --><script data-pjax>function history_calendar_injector_config(){
                var parent_div_git = document.getElementsByClassName('sticky_layout')[0];
                var item_html = '<div class="card-widget card-history"><div class="card-content"><div class="item-headline"><i class="fas fa-clock fa-spin"></i><span>那年今日</span></div><div id="history-baidu" style="height: 100px;overflow: hidden"><div class="history_swiper-container" id="history-container" style="width: 100%;height: 100%"><div class="swiper-wrapper" id="history_container_wrapper" style="height:20px"></div></div></div></div>';
                console.log('已挂载history_calendar')
                // parent_div_git.innerHTML=item_html+parent_div_git.innerHTML // 无报错，但不影响使用(支持pjax跳转)
                parent_div_git.insertAdjacentHTML("afterbegin",item_html) // 有报错，但不影响使用(支持pjax跳转)
            }if( document.getElementsByClassName('sticky_layout')[0] && (location.pathname ==='/'|| '/' ==='all')){

            history_calendar_injector_config()
        } </script><script data-pjax  src="https://cdn.jsdelivr.net/npm/swiper/swiper-bundle.min.js"></script><script data-pjax src="https://cdn.jsdelivr.net/gh/Zfour/Butterfly-card-history/baiduhistory/js/main.js"></script><script data-pjax>
    function butterfly_categories_card_injector_config(){
      var parent_div_git = document.getElementById('recent-posts');
      var item_html = '<style>li.categoryBar-list-item{width:24%;}.categoryBar-list{max-height: 190px;overflow:auto;}.categoryBar-list::-webkit-scrollbar{width:0!important}@media screen and (max-width: 650px){.categoryBar-list{max-height: 160px;}}</style><div class="recent-post-item" style="height:auto;width:100%;padding:0px;"><div id="categoryBar"><ul class="categoryBar-list"><li class="categoryBar-list-item" style="background:url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpicnew6.photophoto.cn%2F20120106%2Fhaimianbaobaotupian-10036689_1.jpg&amp;refer=http%3A%2F%2Fpicnew6.photophoto.cn&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1665648815&amp;t=a3deb15ddd7a38597964c3a05e519bd7);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/Asp-Net/&quot;);" href="javascript:void(0);">Asp.Net</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://npm.elemecdn.com/anzhiyu-blog@1.1.6/img/post/common/site-backgound.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/C-系列/&quot;);" href="javascript:void(0);">C#系列</a><span class="categoryBar-list-count">8</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_bt%2F0%2F13012860773%2F1000.jpg&amp;refer=http%3A%2F%2Finews.gtimg.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1665648865&amp;t=1d2f13b52a7e279e8801545f59eda4e7);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/Hexo重装记录/&quot;);" href="javascript:void(0);">Hexo重装记录</a><span class="categoryBar-list-count">2</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fblog%2F202011%2F07%2F20201107183300_ac0c5.thumb.1000_0.jpeg&amp;refer=http%3A%2F%2Fc-ssl.duitang.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1665648887&amp;t=3d32c6b12a4cf12e5cec3585b79c1fc3);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/EF/&quot;);" href="javascript:void(0);">EF</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fup.enterdesk.com%2Fedpic%2F25%2Feb%2F1f%2F25eb1fd40b5a740c2b79e33f700806e5.jpg&amp;refer=http%3A%2F%2Fup.enterdesk.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1665648908&amp;t=6425ee3bd166b0f5c5ffa6fb18b6937b);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/LOL/&quot;);" href="javascript:void(0);">LOL</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Flmg.jj20.com%2Fup%2Fallimg%2Ftx26%2F36080017392073.jpg&amp;refer=http%3A%2F%2Flmg.jj20.com&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1665650136&amp;t=5cc414d0ee58c9e285218d92f6a95513);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/idea/&quot;);" href="javascript:void(0);">idea</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fn.sinaimg.cn%2Fsinacn10%2F320%2Fw700h420%2F20180907%2F5116-hitesuz6599636.jpg&amp;refer=http%3A%2F%2Fn.sinaimg.cn&amp;app=2002&amp;size=f9999,10000&amp;q=a80&amp;n=0&amp;g=0n&amp;fmt=auto?sec=1665650004&amp;t=6a304aa9cc7435ec1d148b8f99092bc0);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/世界/&quot;);" href="javascript:void(0);">世界</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://s1.ax1x.com/2022/11/15/zAxCi6.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/世界见闻录/&quot;);" href="javascript:void(0);">世界见闻录</a><span class="categoryBar-list-count">8</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://s1.ax1x.com/2022/11/15/zAxFzD.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/前端体系/&quot;);" href="javascript:void(0);">前端体系</a><span class="categoryBar-list-count">19</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://s1.ax1x.com/2022/11/15/zAxnot.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/副业/&quot;);" href="javascript:void(0);">副业</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://s1.ax1x.com/2022/11/15/zAxMJf.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/文案/&quot;);" href="javascript:void(0);">文案</a><span class="categoryBar-list-count">6</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://s1.ax1x.com/2022/11/15/zAxQW8.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/办公日常/&quot;);" href="javascript:void(0);">办公日常</a><span class="categoryBar-list-count">2</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://s1.ax1x.com/2022/11/15/zAx3Qg.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/朝花夕拾/&quot;);" href="javascript:void(0);">朝花夕拾</a><span class="categoryBar-list-count">12</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(https://s1.ax1x.com/2022/11/15/zAxYes.jpg);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/前端/&quot;);" href="javascript:void(0);">前端</a><span class="categoryBar-list-count">20</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(undefined);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/杂七杂八/&quot;);" href="javascript:void(0);">杂七杂八</a><span class="categoryBar-list-count">7</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(undefined);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/简书/&quot;);" href="javascript:void(0);">简书</a><span class="categoryBar-list-count">5</span><span class="categoryBar-list-descr"></span></li><li class="categoryBar-list-item" style="background:url(undefined);"> <a class="categoryBar-list-link" onclick="pjax.loadUrl(&quot;categories/游戏/&quot;);" href="javascript:void(0);">游戏</a><span class="categoryBar-list-count">1</span><span class="categoryBar-list-descr"></span></li></ul></div></div>';
      console.log('已挂载butterfly_categories_card')
      parent_div_git.insertAdjacentHTML("afterbegin",item_html)
      }
    if( document.getElementById('recent-posts') && (location.pathname ==='/'|| '/' ==='all')){
    butterfly_categories_card_injector_config()
    }
  </script><script data-pjax>
  function butterfly_clock_anzhiyu_injector_config(){
    var parent_div_git = document.getElementsByClassName('sticky_layout')[0];
    var item_html = '<div class="card-widget card-clock"><div class="card-glass"><div class="card-background"><div class="card-content"><div id="hexo_electric_clock"><img class="entered loading" id="card-clock-loading" src= "" data-lazy-src="https://cdn.cbd.int/hexo-butterfly-clock-anzhiyu/lib/loading.gif" style="height: 120px; width: 100%;" data-ll-status="loading"/></div></div></div></div></div>';
    console.log('已挂载butterfly_clock_anzhiyu')
    parent_div_git.insertAdjacentHTML("afterbegin",item_html)
    }
  var elist = 'null'.split(',');
  var cpage = location.pathname;
  var epage = '/';
  var qweather_key = '41ea442da35546559913a6a5d54163b2';
  var gaud_map_key = '6b62fbebf584b9a22a85bfccbf90335e';
  var baidu_ak_key = 'undefined';
  var flag = 0;
  var clock_rectangle = '114.35,34.79';
  var clock_default_rectangle_enable = 'true';

  for (var i=0;i<elist.length;i++){
    if (cpage.includes(elist[i])){
      flag++;
    }
  }

  if ((epage ==='all')&&(flag == 0)){
    butterfly_clock_anzhiyu_injector_config();
  }
  else if (epage === cpage){
    butterfly_clock_anzhiyu_injector_config();
  }
  </script><script src="https://widget.qweather.net/simple/static/js/he-simple-common.js?v=2.0"></script><script data-pjax src="https://cdn.cbd.int/hexo-butterfly-clock-anzhiyu/lib/clock.min.js"></script><script data-pjax>
  function butterfly_footer_beautify_injector_config(){
    var parent_div_git = document.getElementById('footer-wrap');
    var item_html = '<div id="workboard"></div><p id="ghbdages"><a class="github-badge" target="_blank" href="https://hexo.io/" style="margin-inline:5px" data-title="博客框架为Hexo_v5.4.0" title=""><img src= "" data-lazy-src="https://img.shields.io/badge/Frame-Hexo-blue?style=flat&amp;logo=hexo" alt=""/></a><a class="github-badge" target="_blank" href="https://butterfly.js.org/" style="margin-inline:5px" data-title="主题版本Butterfly_v4.2.2" title=""><img src= "" data-lazy-src="https://img.shields.io/badge/Theme-Butterfly-6513df?style=flat&amp;logo=bitdefender" alt=""/></a><a class="github-badge" target="_blank" href="https://www.jsdelivr.com/" style="margin-inline:5px" data-title="本站使用JsDelivr为静态资源提供CDN加速" title=""><img src= "" data-lazy-src="https://img.shields.io/badge/CDN-jsDelivr-orange?style=flat&amp;logo=jsDelivr" alt=""/></a><a class="github-badge" target="_blank" href="http://creativecommons.org/licenses/by-nc-sa/4.0/" style="margin-inline:5px" data-title="本站采用知识共享署名-非商业性使用-相同方式共享4.0国际许可协议进行许可" title=""><img src= "" data-lazy-src="https://img.shields.io/badge/Copyright-BY--NC--SA%204.0-d42328?style=flat&amp;logo=Claris" alt=""/></a></p>';
    console.log('已挂载butterfly_footer_beautify')
    parent_div_git.insertAdjacentHTML("beforeend",item_html)
    }
  var elist = 'null'.split(',');
  var cpage = location.pathname;
  var epage = 'all';
  var flag = 0;

  for (var i=0;i<elist.length;i++){
    if (cpage.includes(elist[i])){
      flag++;
    }
  }

  if ((epage ==='all')&&(flag == 0)){
    butterfly_footer_beautify_injector_config();
  }
  else if (epage === cpage){
    butterfly_footer_beautify_injector_config();
  }
  </script><script async src="/js/runtime/runtime.min.js"></script><script data-pjax>
  function butterfly_swiper_injector_config(){
    var parent_div_git = document.getElementById('recent-posts');
    var item_html = '<div class="recent-post-item swiper_container_card" style="height: auto;width: 100%"><div id="random"><div id="random-banner"><canvas id="peoplecanvas"></canvas></div><a id="random-hover" style="width:100%;height:auto;" href="javascript:toRandomPost()" rel="external nofollow noreferrer" one-link-mark="yes"><i class="fa fa-paper-plane" style="margin-left:10px"></i><div style="margin-left:10px">随便逛逛<i class="fa-solid fa-arrow-right" style="margin-left:10px"></i></div></a></div><div class="blog-slider swiper-container-fade swiper-container-horizontal" id="swiper_container"><div class="blog-slider__wrp swiper-wrapper" style="transition-duration: 0ms;"><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;posts/67fcd28d.html&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="https://img2.baidu.com/it/u=4087346614,241521689&amp;fm=253&amp;fmt=auto&amp;app=138&amp;f=JPEG?w=500&amp;h=333" alt="" onerror="this.src=https://cdn.cbd.int/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2022-09-19</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;posts/67fcd28d.html&quot;);" href="javascript:void(0);" alt="">学生人到职业人_心态篇</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;posts/67fcd28d.html&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;posts/8a73f76c.html&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="https://s1.ax1x.com/2022/11/04/xLiBTA.jpg" alt="" onerror="this.src=https://cdn.cbd.int/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2022-11-04</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;posts/8a73f76c.html&quot;);" href="javascript:void(0);" alt="">生活の奇思妙想☞2022</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;posts/8a73f76c.html&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;posts/14e5dae6.html&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="https://s1.ax1x.com/2022/10/21/xcAQDH.jpg" alt="" onerror="this.src=https://cdn.cbd.int/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2022-11-12</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;posts/14e5dae6.html&quot;);" href="javascript:void(0);" alt="">少年自负凌云笔</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;posts/14e5dae6.html&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;posts/9b7092b7.html&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="https://s1.ax1x.com/2022/10/11/xNJbF0.jpg" alt="" onerror="this.src=https://cdn.cbd.int/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2022-09-13</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;posts/9b7092b7.html&quot;);" href="javascript:void(0);" alt="">租房有感</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;posts/9b7092b7.html&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;posts/94bbc7d.html&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="https://s1.ax1x.com/2022/10/11/xNJLWT.jpg" alt="" onerror="this.src=https://cdn.cbd.int/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2022-09-25</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;posts/94bbc7d.html&quot;);" href="javascript:void(0);" alt="">谷歌收藏</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;posts/94bbc7d.html&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div><div class="blog-slider__item swiper-slide" style="width: 750px; opacity: 1; transform: translate3d(0px, 0px, 0px); transition-duration: 0ms;"><a class="blog-slider__img" onclick="pjax.loadUrl(&quot;posts/3b350f14.html&quot;);" href="javascript:void(0);" alt=""><img width="48" height="48" src= "" data-lazy-src="https://s1.ax1x.com/2022/10/11/xNJJd1.jpg" alt="" onerror="this.src=https://cdn.cbd.int/akilar-candyassets/image/loading.gif; this.onerror = null;"/></a><div class="blog-slider__content"><span class="blog-slider__code">2022-09-13</span><a class="blog-slider__title" onclick="pjax.loadUrl(&quot;posts/3b350f14.html&quot;);" href="javascript:void(0);" alt="">阳光不燥、微风正好</a><div class="blog-slider__text">再怎么看我也不知道怎么描述它的啦！</div><a class="blog-slider__button" onclick="pjax.loadUrl(&quot;posts/3b350f14.html&quot;);" href="javascript:void(0);" alt="">详情       </a></div></div></div><div class="blog-slider__pagination swiper-pagination-clickable swiper-pagination-bullets"></div></div></div>';
    console.log('已挂载butterfly_swiper')
    parent_div_git.insertAdjacentHTML("afterbegin",item_html)
    }
  var elist = 'undefined'.split(',');
  var cpage = location.pathname;
  var epage = '/';
  var flag = 0;

  for (var i=0;i<elist.length;i++){
    if (cpage.includes(elist[i])){
      flag++;
    }
  }

  if ((epage ==='all')&&(flag == 0)){
    butterfly_swiper_injector_config();
  }
  else if (epage === cpage){
    butterfly_swiper_injector_config();
  }
  </script><script defer src="https://npm.elemecdn.com/anzhiyu-blog@1.1.6/js/swiper.min.js"></script><script defer data-pjax src="https://cdn.cbd.int/hexo-butterfly-swiper-anzhiyu@1.0.4/lib/swiper_init.js"></script><script data-pjax src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/gsap/3.9.1/gsap.min.js"></script><script defer src="https://npm.elemecdn.com/hexo-butterfly-swiper-anzhiyu@1.0.4/lib/people.min.js"></script><script async src="/anzhiyu/random.js"></script><div class="js-pjax"><script async="async">var arr = document.getElementsByClassName('recent-post-item');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__zoomIn');
    arr[i].setAttribute('data-wow-duration', '1.5s');
    arr[i].setAttribute('data-wow-delay', '200ms');
    arr[i].setAttribute('data-wow-offset', '30');
    arr[i].setAttribute('data-wow-iteration', '1');
  }</script><script async="async">var arr = document.getElementsByClassName('card-widget');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__zoomIn');
    arr[i].setAttribute('data-wow-duration', '');
    arr[i].setAttribute('data-wow-delay', '200ms');
    arr[i].setAttribute('data-wow-offset', '');
    arr[i].setAttribute('data-wow-iteration', '');
  }</script><script async="async">var arr = document.getElementsByClassName('flink-list-card');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__flipInY');
    arr[i].setAttribute('data-wow-duration', '3s');
    arr[i].setAttribute('data-wow-delay', '');
    arr[i].setAttribute('data-wow-offset', '');
    arr[i].setAttribute('data-wow-iteration', '');
  }</script><script async="async">var arr = document.getElementsByClassName('flink-list-card');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__animated');
    arr[i].setAttribute('data-wow-duration', '3s');
    arr[i].setAttribute('data-wow-delay', '');
    arr[i].setAttribute('data-wow-offset', '');
    arr[i].setAttribute('data-wow-iteration', '');
  }</script><script async="async">var arr = document.getElementsByClassName('article-sort-item');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__slideInRight');
    arr[i].setAttribute('data-wow-duration', '1.5s');
    arr[i].setAttribute('data-wow-delay', '');
    arr[i].setAttribute('data-wow-offset', '');
    arr[i].setAttribute('data-wow-iteration', '');
  }</script><script async="async">var arr = document.getElementsByClassName('site-card');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__flipInY');
    arr[i].setAttribute('data-wow-duration', '3s');
    arr[i].setAttribute('data-wow-delay', '');
    arr[i].setAttribute('data-wow-offset', '');
    arr[i].setAttribute('data-wow-iteration', '');
  }</script><script async="async">var arr = document.getElementsByClassName('site-card');
for(var i = 0;i<arr.length;i++){
    arr[i].classList.add('wow');
    arr[i].classList.add('animate__animated');
    arr[i].setAttribute('data-wow-duration', '3s');
    arr[i].setAttribute('data-wow-delay', '');
    arr[i].setAttribute('data-wow-offset', '');
    arr[i].setAttribute('data-wow-iteration', '');
  }</script></div><script defer src="https://cdn.cbd.int/hexo-butterfly-wowjs/lib/wow.min.js"></script><script defer src="https://cdn.cbd.int/hexo-butterfly-wowjs/lib/wow_init.js"></script><script async src="/js/ali_font.js"></script><!-- hexo injector body_end end --><script src="/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"tagMode":false,"debug":false,"model":{"jsonPath":"/live2dw/assets/koharu.model.json"},"display":{"position":"left","width":150,"height":300},"mobile":{"show":false},"log":false,"pluginJsPath":"lib/","pluginModelPath":"assets/","pluginRootPath":"live2dw/"});</script></body></html>